from pathlib import Path
import json
from typing import Any, Dict, List, Optional

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel


# --- Domain models ---


class Answer(BaseModel):
    question_code: str
    value: Any


class SessionCreate(BaseModel):
    language: str
    answers: List[Answer]


class MtsPreparation(BaseModel):
    session_id: str
    proposed_presenting_flowchart: Optional[str] = None
    red_flag_indicators: List[str] = []
    suggested_priority_level: Optional[str] = None


class QuestionOption(BaseModel):
    value: str
    label: str
    icon: str | None = None


class Question(BaseModel):
    code: str
    type: str
    title: str
    options: Optional[List[QuestionOption]] = None
    min: Optional[int] = None
    max: Optional[int] = None


class QuestionsResponse(BaseModel):
    language: str
    questions: List[Question]


BASE_DIR = Path(__file__).resolve().parents[2]
MTS_CONFIG_DIR = BASE_DIR / "mts-config"


def load_questions(language: str) -> QuestionsResponse:
    """Load questions configuration for the given language from mts-config.

    This keeps the triage logic data-driven and allows adding further
    languages by simply providing a new questions.<lang>.json file.
    """

    file_path = MTS_CONFIG_DIR / f"questions.{language}.json"
    if not file_path.exists():
        raise HTTPException(status_code=404, detail=f"No question config for language '{language}'")

    with file_path.open("r", encoding="utf-8") as f:
        raw: Dict[str, Any] = json.load(f)

    return QuestionsResponse(**raw)


def load_flowcharts_config() -> List[Dict[str, Any]]:
    """Load flowchart mapping configuration.

    This maps chief-complaint codes (e.g. "chest_pain") to MTS
    presenting flowchart codes (e.g. "CHEST_PAIN").
    """

    file_path = MTS_CONFIG_DIR / "flowcharts.json"
    if not file_path.exists():
        return []

    with file_path.open("r", encoding="utf-8") as f:
        raw: Dict[str, Any] = json.load(f)

    flowcharts = raw.get("flowcharts", [])
    if not isinstance(flowcharts, list):
        return []
    return flowcharts


app = FastAPI(title="Triage-Fragen API", version="0.3.0")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/health")
async def health() -> Dict[str, str]:
    return {"status": "ok"}


@app.get("/questions/{language}", response_model=QuestionsResponse)
async def get_questions(language: str) -> QuestionsResponse:
    """Return the triage question configuration for the selected language."""

    return load_questions(language)


@app.post("/sessions", response_model=MtsPreparation)
async def create_session(payload: SessionCreate) -> MtsPreparation:
    """Create a triage preparation proposal from the given answers.

    Aktuell wird bewusst nur ein kleiner, aber sinnvoller Ausschnitt
    der Manchester-Triage-Logik abgebildet:

    - Zuordnung von "chief_complaint" zu einem der konfigurierten
      MTS-Präsentations-Flowcharts (10 Pfade in mts-config/flowcharts.json).
    - Ableitung einfacher Red-Flag-Indikatoren wie "severe_pain" aus
      der Schmerzskala.
    - Grobe Prioritätsstufe, insbesondere für Hochrisiko-Flowcharts
      wie Brustschmerz, Atemnot, Kollaps und Intoxikation.
    """

    session_id = "dummy-session-id"

    # Antworten bequem zugreifbar machen
    answers_by_code: Dict[str, Any] = {a.question_code: a.value for a in payload.answers}

    # 1) Flowchart aus chief_complaint bestimmen (Daten-getrieben aus mts-config)
    flowchart: Optional[str] = None
    flowcharts = load_flowcharts_config()

    complaint_to_flowchart: Dict[str, str] = {}
    for fc in flowcharts:
        linked = fc.get("linked_chief_complaints") or []
        if not isinstance(linked, list):
            continue
        for cc in linked:
            # Erstes Mapping gewinnt; spätere Einträge überschreiben nicht
            complaint_to_flowchart.setdefault(cc, fc.get("code"))

    chief = answers_by_code.get("chief_complaint")
    if isinstance(chief, str):
        mapped = complaint_to_flowchart.get(chief)
        if isinstance(mapped, str):
            flowchart = mapped

    # 2) Red-Flag-Indikatoren aus vorhandenen Antworten ableiten
    red_flags: List[str] = []
    severe_pain = False

    # Atemnot: vorgesehen für spätere UI-Erweiterung
    if answers_by_code.get("breathlessness") is True:
        red_flags.append("breathlessness")

    pain_value = answers_by_code.get("pain_intensity")
    if isinstance(pain_value, int):
        if pain_value >= 8:
            red_flags.append("severe_pain")
            severe_pain = True
        elif pain_value >= 5:
            red_flags.append("moderate_pain")

    # 3) Grobe Priorität abhängig vom Flowchart und den Red Flags
    priority: Optional[str] = None

    high_risk_flowcharts = {
        "CHEST_PAIN",
        "SHORTNESS_OF_BREATH",
        "COLLAPSED_ADULT",
        "OVERDOSE_POISONING",
    }

    if "breathlessness" in red_flags:
        # Starke Atemnot ist immer hoch dringlich
        priority = "RED_OR_ORANGE"
    elif severe_pain and flowchart in high_risk_flowcharts:
        # Starke Schmerzen bei Hochrisiko-Präsentation → hohe Dringlichkeit
        priority = "RED_OR_ORANGE"
    elif severe_pain:
        # Starke Schmerzen bei anderen Flowcharts → mindestens erhöhte Dringlichkeit
        priority = "YELLOW_OR_ORANGE"

    return MtsPreparation(
        session_id=session_id,
        proposed_presenting_flowchart=flowchart,
        red_flag_indicators=red_flags,
        suggested_priority_level=priority,
    )
