"""End-to-end tests using external FHIR sample bundles."""

import json
from pathlib import Path

import pytest

from flat_fhir import FlatFHIR

EXTERNAL = Path(__file__).parent / "fixtures" / "external"


def _load(name):
    with open(EXTERNAL / name, encoding="utf-8") as f:
        return json.load(f)


def _external_files():
    """Return all JSON fixture files in external/."""
    return sorted(EXTERNAL.glob("*.json"))


# ── Parametrized: every external fixture loads without error ──

@pytest.mark.parametrize("fixture", _external_files(), ids=lambda p: p.stem)
def test_external_bundle_loads_without_error(fixture):
    """Every external FHIR sample should load without raising."""
    with open(fixture, encoding="utf-8") as f:
        data = json.load(f)
    ff = FlatFHIR(data)
    # Should produce at least some structure
    assert isinstance(ff.sheets(), list)


@pytest.mark.parametrize("fixture", _external_files(), ids=lambda p: p.stem)
def test_external_bundle_round_trip(fixture, tmp_path):
    """FHIR → flat → FHIR round-trip for every external fixture."""
    with open(fixture, encoding="utf-8") as f:
        data = json.load(f)
    ff = FlatFHIR(data)

    # Write to XLSX and back
    xlsx = str(tmp_path / "out.xlsx")
    ff.to_xlsx(xlsx)
    bundle = ff.to_fhir()
    assert bundle["resourceType"] == "Bundle"
    assert bundle["type"] == "collection"


# ── Specific fixture tests ──

def test_hl7_bundle_example():
    """HL7 searchset bundle with MedicationRequest."""
    ff = FlatFHIR(_load("hl7-bundle-example.json"))
    assert isinstance(ff.sheets(), list)


def test_hl7_bundle_transaction():
    """HL7 transaction bundle with Patient operations."""
    ff = FlatFHIR(_load("hl7-bundle-transaction.json"))
    assert isinstance(ff.sheets(), list)


def test_hl7_diagnosticreport_ghp():
    """HL7 collection bundle with DiagnosticReport + Observations."""
    ff = FlatFHIR(_load("hl7-diagnosticreport-ghp.json"))
    sheets = ff.sheets()
    # Should have diagnostic reports and/or labs
    assert isinstance(sheets, list)


def test_ihe_document_bundle():
    """IHE document bundle with Composition."""
    ff = FlatFHIR(_load("ihe-document-bundle.json"))
    assert isinstance(ff.sheets(), list)


def test_smart_synthea_patients():
    """SMART Synthea R4 bundles — large transaction bundles."""
    for name in ["smart-synthea-1.json", "smart-synthea-2.json", "smart-synthea-3.json"]:
        ff = FlatFHIR(_load(name))
        sheets = ff.sheets()
        # Synthea bundles are comprehensive — should have multiple sheet types
        assert len(sheets) >= 3, f"{name} should produce at least 3 sheets, got {sheets}"


def test_smart_diabetes():
    """SMART diabetes patient bundle."""
    ff = FlatFHIR(_load("smart-diabetes.json"))
    sheets = ff.sheets()
    assert len(sheets) >= 1


def test_smart_hca_patients():
    """SMART HCA patient bundles."""
    for name in ["smart-hca-64.json", "smart-hca-67.json", "smart-hca-77.json"]:
        ff = FlatFHIR(_load(name))
        assert isinstance(ff.sheets(), list)


def test_ms_synthea_patient():
    """Microsoft Synthea patient data."""
    ff = FlatFHIR(_load("ms-synthea-patient.json"))
    sheets = ff.sheets()
    assert len(sheets) >= 3


def test_synthea_xlsx_output(tmp_path):
    """Verify XLSX output works for large Synthea bundles."""
    ff = FlatFHIR(_load("smart-synthea-1.json"))
    out = str(tmp_path / "synthea.xlsx")
    ff.to_xlsx(out)
    assert Path(out).exists()
    assert Path(out).stat().st_size > 0


def test_synthea_parquet_output(tmp_path):
    """Verify Parquet output works for large Synthea bundles."""
    pytest.importorskip("pyarrow")
    ff = FlatFHIR(_load("smart-synthea-1.json"))
    out = str(tmp_path / "synthea.parquet")
    ff.to_parquet(out)
    assert Path(out).exists()


def test_synthea_json_output(tmp_path):
    """Verify JSON output works for large Synthea bundles."""
    ff = FlatFHIR(_load("smart-synthea-1.json"))
    out = str(tmp_path / "synthea.json")
    ff.to_json(out)
    with open(out) as f:
        data = json.load(f)
    assert isinstance(data, dict)


def test_synthea_prompt_output():
    """Verify prompt output for Synthea bundles."""
    ff = FlatFHIR(_load("smart-synthea-1.json"))
    prompt = ff.to_prompt()
    assert isinstance(prompt, str)
    assert len(prompt) > 0


def test_synthea_prompt_truncation():
    """Verify max_tokens truncation."""
    ff = FlatFHIR(_load("smart-synthea-1.json"))
    short = ff.to_prompt(max_tokens=50)
    assert len(short) <= 250  # 50 * 4 + some buffer for truncation marker


def test_merge_external_bundles():
    """Merge multiple external bundles."""
    from flat_fhir import merge
    bundles = [
        _load("smart-hca-64.json"),
        _load("smart-hca-67.json"),
    ]
    ff = merge(bundles)
    assert isinstance(ff.sheets(), list)


def test_csv_output(tmp_path):
    """Verify CSV output."""
    ff = FlatFHIR(_load("smart-synthea-1.json"))
    out = str(tmp_path / "vitals.csv")
    ff.to_csv(out, sheet="vitals")
    assert Path(out).exists()
