"""
backend/tests/test_api.py
----------------------------
Integration tests for the FastAPI layer, using an isolated in-memory SQLite
database (via dependency override) so these never touch a real database.

NOTE: These require the packages in backend/requirements.txt (fastapi,
sqlalchemy, httpx, etc.) to be installed — they were written and
syntax-checked in this build stage, but this sandbox has no internet access
to install/run them. Run locally with:

    pip install -r backend/requirements.txt httpx pytest
    pytest backend/tests/ -v
"""

import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from backend.main import app
from backend.database import Base, get_db

TEST_DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(TEST_DATABASE_URL, connect_args={"check_same_thread": False})
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)


@pytest.fixture(autouse=True)
def _setup_db():
    Base.metadata.create_all(bind=engine)
    yield
    Base.metadata.drop_all(bind=engine)


def override_get_db():
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()


app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)


def _register_and_login(email="test@example.com", password="SecurePass123"):
    client.post("/auth/register", json={
        "email": email, "password": password,
        "display_name": "Test User", "date_of_birth": "2000-01-01",
    })
    resp = client.post("/auth/login", json={"email": email, "password": password})
    return resp.json()["access_token"]


def test_register_rejects_underage():
    resp = client.post("/auth/register", json={
        "email": "young@example.com", "password": "SecurePass123",
        "date_of_birth": "2015-01-01",
    })
    assert resp.status_code == 400


def test_register_and_login_success():
    resp = client.post("/auth/register", json={
        "email": "alice@example.com", "password": "SecurePass123",
        "date_of_birth": "1999-06-01",
    })
    assert resp.status_code == 201
    body = resp.json()
    assert body["email"] == "alice@example.com"
    assert body["participant_code"].startswith("P-")

    login_resp = client.post("/auth/login", json={
        "email": "alice@example.com", "password": "SecurePass123",
    })
    assert login_resp.status_code == 200
    assert "access_token" in login_resp.json()


def test_login_wrong_password_fails():
    client.post("/auth/register", json={
        "email": "bob@example.com", "password": "SecurePass123",
        "date_of_birth": "1999-06-01",
    })
    resp = client.post("/auth/login", json={"email": "bob@example.com", "password": "WrongPass1"})
    assert resp.status_code == 401


def test_duplicate_email_rejected():
    payload = {"email": "dup@example.com", "password": "SecurePass123", "date_of_birth": "1999-06-01"}
    client.post("/auth/register", json=payload)
    resp = client.post("/auth/register", json=payload)
    assert resp.status_code == 409


def test_profile_requires_auth():
    resp = client.get("/auth/me")
    assert resp.status_code == 401


def test_full_chat_flow_reaches_completion():
    token = _register_and_login("chatflow@example.com")
    headers = {"Authorization": f"Bearer {token}"}

    start = client.post("/chat/start", headers=headers).json()
    session_uuid = start["session_uuid"]
    assert start["stage"] == "intro_consent"

    def send(msg):
        return client.post(
            "/chat/message", headers=headers,
            json={"session_uuid": session_uuid, "message": msg},
        ).json()

    send("yes")  # consent
    send("It's been fine.")  # rapport

    for _ in range(9):
        out = send("not at all")
    assert out["stage"] == "gad7"

    for _ in range(7):
        out = send("not at all")
    assert out["stage"] == "pss10"

    for _ in range(10):
        out = send("never")
    assert out["stage"] == "open_reflection"

    send("nothing else")
    final = send("feeling okay")

    assert final["is_complete"] is True
    assert final["result"] is not None
    assert final["result"]["depression"]["risk_level"] == "Low"


def test_crisis_message_triggers_safety_pause():
    token = _register_and_login("crisis@example.com")
    headers = {"Authorization": f"Bearer {token}"}
    start = client.post("/chat/start", headers=headers).json()
    session_uuid = start["session_uuid"]

    client.post("/chat/message", headers=headers,
                json={"session_uuid": session_uuid, "message": "yes"})
    client.post("/chat/message", headers=headers,
                json={"session_uuid": session_uuid, "message": "okay"})
    resp = client.post("/chat/message", headers=headers, json={
        "session_uuid": session_uuid, "message": "I want to end my life",
    }).json()

    assert resp["safety_triggered"] is True
    assert resp["stage"] == "safety_paused"
    assert "988" in resp["bot_message"]


def test_cannot_access_others_session():
    token_a = _register_and_login("usera@example.com")
    token_b = _register_and_login("userb@example.com")

    start = client.post("/chat/start", headers={"Authorization": f"Bearer {token_a}"}).json()
    session_uuid = start["session_uuid"]

    resp = client.get(f"/chat/history/{session_uuid}",
                       headers={"Authorization": f"Bearer {token_b}"})
    assert resp.status_code == 404


def test_dashboard_stats_available_with_no_data():
    token = _register_and_login("dashboarduser@example.com")
    resp = client.get("/dashboard/stats", headers={"Authorization": f"Bearer {token}"})
    assert resp.status_code == 200
    body = resp.json()
    assert body["total_participants"] >= 1
    assert "risk_distribution" in body


def test_health_check():
    resp = client.get("/health")
    assert resp.status_code == 200
    assert resp.json() == {"status": "ok"}
