"""Live OpenAI integration test.

Makes a real OpenAI API call to verify the full stack (FastAPI -> auth ->
OpenAI client -> structured output parsing) works against a real key.

Auto-skips when neither CRYSTALLISE_OPENAI_API_KEY nor OPENAI_API_KEY is set,
so this file is safe to leave in the default test suite.

Run explicitly:

    CRYSTALLISE_OPENAI_API_KEY=sk-... pytest tests/integration -v

Cost per run is a few tenths of a cent on gpt-4.1 (the default criteria model).
"""

from __future__ import annotations

import os

import pytest
from fastapi.testclient import TestClient

from api.main import app

_HAS_KEY = bool(os.environ.get("CRYSTALLISE_OPENAI_API_KEY") or os.environ.get("OPENAI_API_KEY"))

pytestmark = [
    pytest.mark.integration,
    pytest.mark.skipif(not _HAS_KEY, reason="No OpenAI API key (set CRYSTALLISE_OPENAI_API_KEY or OPENAI_API_KEY)"),
]


client = TestClient(app)


def test_criteria_picos_live_openai():
    """Hit /v1/criteria/picos against real OpenAI and verify response shape.

    This is a smoke test, not a correctness test — we assert structural
    properties (keys present, non-empty strings) rather than content, because
    LLM output is non-deterministic.
    """
    response = client.post(
        "/v1/criteria/picos",
        json={
            "project_description": (
                "A systematic review of randomised controlled trials comparing "
                "metformin to placebo in adults with type 2 diabetes, with "
                "HbA1c reduction as the primary outcome."
            ),
            "research_questions": [
                "Does metformin reduce HbA1c compared to placebo in adults with type 2 diabetes?",
            ],
        },
    )

    assert response.status_code == 200, response.text
    data = response.json()
    assert "elements" in data, data
    elements = data["elements"]
    assert isinstance(elements, dict)

    for key in ("population", "intervention", "comparison", "outcome"):
        assert key in elements, f"Missing '{key}' in {list(elements.keys())}"
        value = elements[key]
        assert isinstance(value, str) and value.strip(), f"'{key}' should be a non-empty string, got: {value!r}"


def test_analyze_question_live_openai():
    """Hit /v1/criteria/analyze-question against real OpenAI and verify response shape.

    Uses a deliberately thin question so the model is likely to return
    "could_improve" with missing_elements. We only assert shape, not content.
    """
    response = client.post(
        "/v1/criteria/analyze-question",
        json={"research_question": "Does exercise help depression?"},
    )

    assert response.status_code == 200, response.text
    data = response.json()

    assert data.get("status") in ("ready", "could_improve"), data
    assert isinstance(data.get("missing_elements"), list)
    assert all(isinstance(e, str) for e in data["missing_elements"])
    suggestion = data.get("suggestion")
    assert isinstance(suggestion, str) and suggestion.strip(), (
        f"'suggestion' should be a non-empty string, got: {suggestion!r}"
    )
