"""Integration tests for PATCH /ai-sessions/{sid}/suggested-fixes/{fid}/script."""
from __future__ import annotations

import pytest
from httpx import AsyncClient
from sqlalchemy import select
from uuid import UUID, uuid4

from app.models.ai_session import AISession
from app.models.session_suggested_fix import SessionSuggestedFix


async def _make_session_with_fix(
    test_db, user, *, status: str = "proposed", with_script: bool = False,
) -> tuple[str, str]:
    """Create a pilot session + suggested fix for tests. Returns (sid, fid)."""
    session = AISession(
        id=uuid4(),
        user_id=user["user_data"]["id"],
        account_id=user["user_data"]["account_id"],
        session_type="tshoot",
        intake_type="psa_ticket",
        intake_content={},
        title="QA",
        status="active",
        confidence_tier="exploring",
        confidence_score=0.0,
    )
    test_db.add(session)
    await test_db.flush()
    fix = SessionSuggestedFix(
        id=uuid4(),
        session_id=session.id,
        account_id=user["user_data"]["account_id"],
        title="QA: test fix",
        description="desc",
        confidence_pct=80,
        status=status,
        ai_drafted_script="pre-existing" if with_script else None,
    )
    test_db.add(fix)
    await test_db.commit()
    return str(session.id), str(fix.id)


@pytest.mark.asyncio
async def test_patch_script_happy_path(
    client: AsyncClient, test_user, auth_headers, test_db
):
    sid, fid = await _make_session_with_fix(test_db, test_user)
    r = await client.patch(
        f"/api/v1/ai-sessions/{sid}/suggested-fixes/{fid}/script",
        json={"ai_drafted_script": "Write-Host 'hello'"},
        headers=auth_headers,
    )
    assert r.status_code == 200, r.text
    body = r.json()
    assert body["ai_drafted_script"] == "Write-Host 'hello'"
    assert body["applied_at"] is None  # draft != apply
    assert body["status"] == "proposed"


@pytest.mark.asyncio
async def test_patch_script_bumps_state_version(
    client: AsyncClient, test_user, auth_headers, test_db
):
    sid, fid = await _make_session_with_fix(test_db, test_user)
    before = await test_db.scalar(
        select(AISession.state_version).where(AISession.id == UUID(sid))
    )
    r = await client.patch(
        f"/api/v1/ai-sessions/{sid}/suggested-fixes/{fid}/script",
        json={"ai_drafted_script": "echo hi"},
        headers=auth_headers,
    )
    assert r.status_code == 200
    after = await test_db.scalar(
        select(AISession.state_version).where(AISession.id == UUID(sid))
    )
    assert after == (before or 0) + 1


@pytest.mark.asyncio
async def test_patch_script_rejects_terminal_fix(
    client: AsyncClient, test_user, auth_headers, test_db
):
    sid, fid = await _make_session_with_fix(test_db, test_user, status="applied_success")
    r = await client.patch(
        f"/api/v1/ai-sessions/{sid}/suggested-fixes/{fid}/script",
        json={"ai_drafted_script": "echo hi"},
        headers=auth_headers,
    )
    assert r.status_code == 409


@pytest.mark.asyncio
async def test_patch_script_rejects_empty_body(
    client: AsyncClient, test_user, auth_headers, test_db
):
    sid, fid = await _make_session_with_fix(test_db, test_user)
    r = await client.patch(
        f"/api/v1/ai-sessions/{sid}/suggested-fixes/{fid}/script",
        json={"ai_drafted_script": ""},
        headers=auth_headers,
    )
    assert r.status_code == 422  # pydantic min_length=1


@pytest.mark.asyncio
async def test_patch_script_404_on_wrong_session(
    client: AsyncClient, test_user, auth_headers, test_db
):
    _, fid = await _make_session_with_fix(test_db, test_user)
    wrong_sid = str(uuid4())
    r = await client.patch(
        f"/api/v1/ai-sessions/{wrong_sid}/suggested-fixes/{fid}/script",
        json={"ai_drafted_script": "echo hi"},
        headers=auth_headers,
    )
    assert r.status_code == 404
