"""API-level webhook idempotency and intake tests."""

from __future__ import annotations

import uuid

import pytest
from sqlalchemy import select

from packages.db.models import AuditEvent, Run, WorkflowState
from tests.conftest import load_story


def _created_payload(key: str = "SALES-101"):
    return {
        "webhookEvent": "jira:issue_created",
        "issue": {
            "key": key,
            "fields": {
                "project": {"key": "SALES"},
                "status": {"name": "Ready for Agent"},
                "issuetype": {"name": "Story"},
                "labels": ["agent-nova"],
                "summary": "Test",
            },
        },
    }


@pytest.mark.asyncio
async def test_health(api_client):
    resp = await api_client.get("/health")
    assert resp.status_code == 200
    assert resp.json()["status"] == "ok"


@pytest.mark.asyncio
async def test_webhook_queues_and_idempotent(api_client, mock_jira, db_session):
    mock_jira.seed(load_story("SALES-101"))
    headers = {"X-Atlassian-Webhook-Identifier": "delivery-abc"}
    r1 = await api_client.post("/webhooks/jira", json=_created_payload(), headers=headers)
    assert r1.status_code == 200
    body1 = r1.json()
    assert body1["status"] == "queued"
    run_id = body1["run_id"]

    # Duplicate delivery
    r2 = await api_client.post("/webhooks/jira", json=_created_payload(), headers=headers)
    assert r2.json()["status"] == "duplicate"

    # Second event while active
    r3 = await api_client.post(
        "/webhooks/jira",
        json=_created_payload(),
        headers={"X-Atlassian-Webhook-Identifier": "delivery-xyz"},
    )
    assert r3.json()["status"] == "ignored"
    assert r3.json()["reason"] == "active_run_exists"

    run = await db_session.get(Run, uuid.UUID(run_id))
    assert run is not None
    assert run.state in {
        WorkflowState.DESIGN_REVIEW,
        WorkflowState.NEEDS_CLARIFICATION,
        WorkflowState.ANALYZING,
        WorkflowState.ARCHITECTING,
        WorkflowState.IMPLEMENTING,
        WorkflowState.REVIEWING,
        WorkflowState.TESTING,
    }


@pytest.mark.asyncio
async def test_webhook_moves_jira_to_in_progress(api_client, mock_jira, db_session):
    issue = load_story("SALES-101")
    issue.status = "To Do"
    mock_jira.seed(issue)

    r1 = await api_client.post(
        "/webhooks/jira",
        json=_created_payload("SALES-101"),
        headers={"X-Atlassian-Webhook-Identifier": "delivery-inprog"},
    )
    assert r1.json()["status"] == "queued"
    run_id = uuid.UUID(r1.json()["run_id"])

    assert mock_jira.issues["SALES-101"].status == "In Progress"
    assert {"key": "SALES-101", "status": "In Progress"} in mock_jira.transitions_posted

    events = (
        await db_session.execute(
            select(AuditEvent).where(
                AuditEvent.run_id == run_id,
                AuditEvent.event_type == "jira.transition",
            )
        )
    ).scalars().all()
    assert len(events) == 1
    assert "In Progress" in events[0].message


@pytest.mark.asyncio
async def test_webhook_continues_when_jira_transition_fails(api_client, mock_jira, db_session):
    mock_jira.seed(load_story("SALES-101"))
    mock_jira.fail_transitions = True

    r1 = await api_client.post(
        "/webhooks/jira",
        json=_created_payload("SALES-101"),
        headers={"X-Atlassian-Webhook-Identifier": "delivery-fail-trans"},
    )
    assert r1.json()["status"] == "queued"
    run_id = uuid.UUID(r1.json()["run_id"])

    run = await db_session.get(Run, run_id)
    assert run is not None

    events = (
        await db_session.execute(
            select(AuditEvent).where(
                AuditEvent.run_id == run_id,
                AuditEvent.event_type == "jira.transition_failed",
            )
        )
    ).scalars().all()
    assert len(events) == 1


@pytest.mark.asyncio
async def test_webhook_resume_path(api_client, mock_jira, db_session):
    mock_jira.seed(load_story("SALES-102"))
    r1 = await api_client.post(
        "/webhooks/jira",
        json=_created_payload("SALES-102"),
        headers={"X-Atlassian-Webhook-Identifier": "d-102-a"},
    )
    assert r1.json()["status"] == "queued"
    run_id = r1.json()["run_id"]
    run = await db_session.get(Run, uuid.UUID(run_id))
    assert run.state == WorkflowState.NEEDS_CLARIFICATION

    clarified = load_story("SALES-110")
    clarified.key = "SALES-102"
    mock_jira.seed(clarified)

    comment_payload = {
        "webhookEvent": "comment_created",
        "issue": {
            "key": "SALES-102",
            "fields": {
                "project": {"key": "SALES"},
                "status": {"name": "Ready for Agent"},
                "issuetype": {"name": "Story"},
                "labels": ["agent-nova"],
            },
        },
        "comment": {
            "author": {"accountId": "human-1"},
            "body": "1. Create Task when Lead is Qualified. AC: subject Follow up Qualified Lead.",
        },
    }
    r2 = await api_client.post(
        "/webhooks/jira",
        json=comment_payload,
        headers={"X-Atlassian-Webhook-Identifier": "d-102-b"},
    )
    assert r2.json()["status"] == "resumed"
    await db_session.refresh(run)
    assert run.state == WorkflowState.DESIGN_REVIEW


@pytest.mark.asyncio
async def test_webhook_design_review_resume(api_client, mock_jira, db_session):
    mock_jira.seed(load_story("SALES-101"))
    r1 = await api_client.post(
        "/webhooks/jira",
        json=_created_payload("SALES-101"),
        headers={"X-Atlassian-Webhook-Identifier": "d-101-a"},
    )
    assert r1.json()["status"] == "queued"
    run_id = r1.json()["run_id"]
    run = await db_session.get(Run, uuid.UUID(run_id))
    assert run.state == WorkflowState.DESIGN_REVIEW

    comment_payload = {
        "webhookEvent": "comment_created",
        "issue": {
            "key": "SALES-101",
            "fields": {
                "project": {"key": "SALES"},
                "status": {"name": "Ready for Agent"},
                "issuetype": {"name": "Story"},
                "labels": ["agent-nova"],
            },
        },
        "comment": {
            "author": {"accountId": "human-1"},
            "body": "Approved — ship it",
        },
    }
    r2 = await api_client.post(
        "/webhooks/jira",
        json=comment_payload,
        headers={"X-Atlassian-Webhook-Identifier": "d-101-b"},
    )
    assert r2.json()["status"] == "resumed"
    assert r2.json().get("decision") == "approve"
    await db_session.refresh(run)
    assert run.state == WorkflowState.PR_CREATED
    assert run.artifacts.get("design_approved") is True
    assert run.branch_name
    assert run.pr_url
