"""Phase 13.4 — Patient Portal tests."""
from __future__ import annotations

from datetime import datetime, timedelta, timezone

import pytest

from app.tests.conftest import TENANT_A, TENANT_B, tenant_headers


def patient_headers(tenant_id, patient_id):
    h = tenant_headers(tenant_id)
    h["X-Patient-ID"] = str(patient_id)
    return h


async def _seed_patient(client):
    headers = tenant_headers(TENANT_A)
    clinic = await client.post(
        "/api/v1/clinics",
        headers=headers,
        json={"code": "CLN134", "name": "Portal Clinic", "status": "active"},
    )
    clinic_id = clinic.json()["id"]
    doctor = await client.post(
        "/api/v1/doctors",
        headers=headers,
        json={
            "user_id": "doc-134",
            "clinic_id": clinic_id,
            "code": "DOC134",
            "display_name": "Dr Portal",
        },
    )
    doctor_id = doctor.json()["id"]
    patient = await client.post(
        "/api/v1/patients",
        headers=headers,
        json={
            "user_id": "pat-134",
            "code": "PAT134",
            "display_name": "Portal Patient",
            "contact": {"phone": "+989121234567"},
        },
    )
    patient_id = patient.json()["id"]
    return clinic_id, doctor_id, patient_id


@pytest.mark.asyncio
async def test_patient_portal_profile_and_appointments(client):
    clinic_id, doctor_id, patient_id = await _seed_patient(client)
    headers = patient_headers(TENANT_A, patient_id)

    profile = await client.get("/api/v1/patient-portal/me", headers=headers)
    assert profile.status_code == 200
    assert profile.json()["patient_id"] == patient_id

    updated = await client.patch(
        "/api/v1/patient-portal/me",
        headers=headers,
        json={"preferred_language": "en", "version": profile.json()["version"]},
    )
    assert updated.status_code == 200
    assert updated.json()["preferred_language"] == "en"

    start = datetime(2026, 10, 1, 9, 0, tzinfo=timezone.utc)
    booked = await client.post(
        "/api/v1/patient-portal/appointments",
        headers=headers,
        json={
            "clinic_id": clinic_id,
            "doctor_id": doctor_id,
            "patient_id": patient_id,
            "code": "APT-PORTAL",
            "scheduled_start": start.isoformat(),
            "scheduled_end": (start + timedelta(minutes=30)).isoformat(),
        },
    )
    assert booked.status_code == 201

    listed = await client.get("/api/v1/patient-portal/appointments", headers=headers)
    assert listed.status_code == 200
    assert listed.json()["total"] >= 1


@pytest.mark.asyncio
async def test_patient_isolation(client):
    _, _, patient_a = await _seed_patient(client)
    headers_b = tenant_headers(TENANT_B)
    patient_b = await client.post(
        "/api/v1/patients",
        headers=headers_b,
        json={"user_id": "pat-b", "code": "PATB", "display_name": "Other"},
    )
    assert patient_b.status_code == 201

    denied = await client.get(
        "/api/v1/patient-portal/me",
        headers=patient_headers(TENANT_A, patient_b.json()["id"]),
    )
    assert denied.status_code == 404


@pytest.mark.asyncio
async def test_patient_documents_and_notification_prefs(client):
    _, _, patient_id = await _seed_patient(client)
    headers = patient_headers(TENANT_A, patient_id)

    doc = await client.post(
        "/api/v1/patient-portal/documents",
        headers=headers,
        json={
            "code": "DOC1",
            "title": "Lab Result",
            "storage_file_ref": "storage://lab-1",
        },
    )
    assert doc.status_code == 201

    pref = await client.put(
        "/api/v1/patient-portal/notification-preferences",
        headers=headers,
        json={"channel": "sms", "template_key": "healthcare.appointment.reminder", "enabled": True},
    )
    assert pref.status_code == 200


@pytest.mark.asyncio
async def test_phase_134_capabilities(client):
    caps = await client.get("/capabilities")
    assert caps.json()["features"]["patient_portal"] is True
