"""Tests for interview prep endpoints: research GET/generate/task, contacts GET."""
import pytest
from unittest.mock import patch, MagicMock
from fastapi.testclient import TestClient


@pytest.fixture
def client():
    import sys
    sys.path.insert(0, "/Library/Development/CircuitForge/peregrine/.worktrees/feature-vue-spa")
    from dev_api import app
    return TestClient(app)


# ── /api/jobs/{id}/research ─────────────────────────────────────────────────

def test_get_research_found(client):
    """Returns research row (minus raw_output) when present."""
    mock_row = {
        "job_id": 1,
        "company_brief": "Acme Corp makes anvils.",
        "ceo_brief": "Wile E Coyote",
        "talking_points": "- Ask about roadrunner containment",
        "tech_brief": "Python, Rust",
        "funding_brief": "Series B",
        "red_flags": None,
        "accessibility_brief": None,
        "generated_at": "2026-03-20T12:00:00",
    }
    mock_db = MagicMock()
    mock_db.execute.return_value.fetchone.return_value = mock_row
    with patch("dev_api._get_db", return_value=mock_db):
        resp = client.get("/api/jobs/1/research")
    assert resp.status_code == 200
    data = resp.json()
    assert data["company_brief"] == "Acme Corp makes anvils."
    assert "raw_output" not in data


def test_get_research_not_found(client):
    """Returns 404 when no research row exists for job."""
    mock_db = MagicMock()
    mock_db.execute.return_value.fetchone.return_value = None
    with patch("dev_api._get_db", return_value=mock_db):
        resp = client.get("/api/jobs/99/research")
    assert resp.status_code == 404


# ── /api/jobs/{id}/research/generate ────────────────────────────────────────

def test_generate_research_new_task(client):
    """POST generate returns task_id and is_new=True for fresh submission."""
    with patch("scripts.task_runner.submit_task", return_value=(42, True)):
        resp = client.post("/api/jobs/1/research/generate")
    assert resp.status_code == 200
    data = resp.json()
    assert data["task_id"] == 42
    assert data["is_new"] is True


def test_generate_research_duplicate_task(client):
    """POST generate returns is_new=False when task already queued."""
    with patch("scripts.task_runner.submit_task", return_value=(17, False)):
        resp = client.post("/api/jobs/1/research/generate")
    assert resp.status_code == 200
    data = resp.json()
    assert data["is_new"] is False


def test_generate_research_error(client):
    """POST generate returns 500 when submit_task raises."""
    with patch("scripts.task_runner.submit_task", side_effect=Exception("LLM unavailable")):
        resp = client.post("/api/jobs/1/research/generate")
    assert resp.status_code == 500


# ── /api/jobs/{id}/research/task ────────────────────────────────────────────

def test_research_task_none(client):
    """Returns status=none when no background task exists for job."""
    mock_db = MagicMock()
    mock_db.execute.return_value.fetchone.return_value = None
    with patch("dev_api._get_db", return_value=mock_db):
        resp = client.get("/api/jobs/1/research/task")
    assert resp.status_code == 200
    data = resp.json()
    assert data["status"] == "none"
    assert data["stage"] is None
    assert data["message"] is None


def test_research_task_running(client):
    """Returns current status/stage/message for an active task."""
    mock_row = {"status": "running", "stage": "Scraping company site", "error": None}
    mock_db = MagicMock()
    mock_db.execute.return_value.fetchone.return_value = mock_row
    with patch("dev_api._get_db", return_value=mock_db):
        resp = client.get("/api/jobs/1/research/task")
    assert resp.status_code == 200
    data = resp.json()
    assert data["status"] == "running"
    assert data["stage"] == "Scraping company site"
    assert data["message"] is None


def test_research_task_failed(client):
    """Returns message (mapped from error column) for failed task."""
    mock_row = {"status": "failed", "stage": None, "error": "LLM timeout"}
    mock_db = MagicMock()
    mock_db.execute.return_value.fetchone.return_value = mock_row
    with patch("dev_api._get_db", return_value=mock_db):
        resp = client.get("/api/jobs/1/research/task")
    assert resp.status_code == 200
    data = resp.json()
    assert data["status"] == "failed"
    assert data["message"] == "LLM timeout"


# ── /api/jobs/{id}/contacts ──────────────────────────────────────────────────

def test_get_contacts_empty(client):
    """Returns empty list when job has no contacts."""
    mock_db = MagicMock()
    mock_db.execute.return_value.fetchall.return_value = []
    with patch("dev_api._get_db", return_value=mock_db):
        resp = client.get("/api/jobs/1/contacts")
    assert resp.status_code == 200
    assert resp.json() == []


def test_get_contacts_list(client):
    """Returns list of contact dicts for job."""
    mock_rows = [
        {"id": 1, "direction": "inbound", "subject": "Interview next week",
         "from_addr": "hr@acme.com", "body": "Hi! We'd like to...", "received_at": "2026-03-19T10:00:00"},
        {"id": 2, "direction": "outbound", "subject": "Re: Interview next week",
         "from_addr": None, "body": "Thank you!", "received_at": "2026-03-19T11:00:00"},
    ]
    mock_db = MagicMock()
    mock_db.execute.return_value.fetchall.return_value = mock_rows
    with patch("dev_api._get_db", return_value=mock_db):
        resp = client.get("/api/jobs/1/contacts")
    assert resp.status_code == 200
    data = resp.json()
    assert len(data) == 2
    assert data[0]["direction"] == "inbound"
    assert data[1]["direction"] == "outbound"


def test_get_contacts_ordered_by_received_at(client):
    """Most recent contacts appear first (ORDER BY received_at DESC)."""
    mock_db = MagicMock()
    mock_db.execute.return_value.fetchall.return_value = []
    with patch("dev_api._get_db", return_value=mock_db):
        resp = client.get("/api/jobs/99/contacts")
    # Verify the SQL contains ORDER BY received_at DESC
    call_args = mock_db.execute.call_args
    sql = call_args[0][0]
    assert "ORDER BY received_at DESC" in sql
