"""
Converting a plot-availability inquiry (POST /api/public/plot-inquiries)
into an Opportunity must carry the plot_id forward — otherwise the
proposal-compose screen has no way to know which plot the family actually
asked about (it goes to `hold`, not `vacant`, so it drops out of the
vacant-plots list the moment the inquiry lands).

Lives under tests/apps/sales/ (not tests/apps/public/) because the
conversion endpoint is behind require_feature("sales"), which needs this
directory's professional-plan `test_account` override
(tests/apps/sales/conftest.py) rather than the shared starter-plan one.
"""
import pytest
from httpx import AsyncClient
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from src.apps.plots.models.plot import Plot
from src.apps.sales.models.contact_inquiry import ContactInquiry
from src.apps.sales.models.opportunity import Opportunity

PLOT_INQUIRY_URL = "/api/public/plot-inquiries"

VALID_PAYLOAD = {
    "plot_ref": "1-4",
    "sender_name": "Sophie Lavoie",
    "sender_email": "sophie@example.ca",
    "sender_phone": "(613) 555-0100",
    "relationship": "Planning for a parent",
    "message": "I'd like to learn more about plot 1-4 for my mother.",
}


@pytest.fixture(autouse=True)
def clear_rate_limit():
    """Clear the Redis rate-limit counter before each test to prevent bleed."""
    import redis
    from src.core.config import settings
    r = redis.from_url(settings.REDIS_URL, decode_responses=True)
    for key in r.keys("rate:plot-inquiry:*"):
        r.delete(key)
    yield
    r.close()


@pytest.mark.asyncio
async def test_plot_inquiry_converts_to_opportunity_with_plot_id(
    client: AsyncClient, db_session: AsyncSession, admin_token: str, test_account
):
    plot = Plot(tenant_id=test_account.id, plot_ref="1-4", status="vacant")
    db_session.add(plot)
    await db_session.flush()

    payload = {**VALID_PAYLOAD, "plot_id": str(plot.id)}
    response = await client.post(
        PLOT_INQUIRY_URL, json=payload, headers={"X-Tenant-ID": str(test_account.id)}
    )
    assert response.status_code == 201
    inq_id = response.json()["data"]["id"]

    # The inquiry puts the plot on hold — it must no longer be vacant.
    await db_session.refresh(plot)
    assert plot.status == "hold"

    inq_result = await db_session.execute(select(ContactInquiry).where(ContactInquiry.id == inq_id))
    assert inq_result.scalar_one().plot_id == plot.id

    convert_resp = await client.post(
        f"/api/v1/sales/inquiries/{inq_id}/convert",
        headers={"Authorization": f"Bearer {admin_token}", "X-Tenant-ID": str(test_account.id)},
    )
    assert convert_resp.status_code == 201, convert_resp.text
    opportunity_id = convert_resp.json()["data"]["opportunity_id"]

    opp_result = await db_session.execute(select(Opportunity).where(Opportunity.id == opportunity_id))
    opp = opp_result.scalar_one()
    assert opp.plot_id == plot.id
