"""Extract data from FHIR AllergyIntolerance resources."""

from __future__ import annotations

from typing import Any

from fhir_agent_tools._parse import _error, _parse_resource
from fhir_agent_tools._utils import format_codeable_concept, format_reference


def get_allergy_summary(
    allergy: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Extract key AllergyIntolerance fields for LLM consumption."""
    try:
        if allergy is None or (isinstance(allergy, str) and allergy.strip() == ""):
            err = _error("empty_input", "No input provided")
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(err["error"])
            return err

        resource = _parse_resource(allergy, "AllergyIntolerance")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        reactions = []
        for r in getattr(resource, "reaction", None) or []:
            manifest = [format_codeable_concept(m) for m in (getattr(r, "manifestation", None) or [])]
            reactions.append({"manifestation": manifest, "severity": str(getattr(r, "severity", None)) if getattr(r, "severity", None) else None})

        data = {
            "id": getattr(resource, "id", None),
            "code": format_codeable_concept(getattr(resource, "code", None)),
            "criticality": str(getattr(resource, "criticality", None)) if getattr(resource, "criticality", None) else None,
            "clinicalStatus": format_codeable_concept(getattr(resource, "clinicalStatus", None)),
            "verificationStatus": format_codeable_concept(getattr(resource, "verificationStatus", None)),
            "patient": format_reference(getattr(resource, "patient", None)),
            "reaction": reactions,
        }

        result = {"success": True, "data": data}
        if raise_on_error:
            return result["data"]
        return result

    except Exception as e:
        err = _error("unexpected_error", str(e), details=repr(e))
        if raise_on_error:
            from fhir_agent_tools._parse import FhirExtractError
            raise FhirExtractError(err["error"])
        return err


def get_allergy_substance(
    allergy: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get allergy substance (code)."""
    try:
        if allergy is None or (isinstance(allergy, str) and allergy.strip() == ""):
            err = _error("empty_input", "No input provided")
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(err["error"])
            return err

        resource = _parse_resource(allergy, "AllergyIntolerance")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        code = format_codeable_concept(getattr(resource, "code", None))
        result = {"success": True, "data": code}
        if raise_on_error:
            return result["data"]
        return result

    except Exception as e:
        err = _error("unexpected_error", str(e), details=repr(e))
        if raise_on_error:
            from fhir_agent_tools._parse import FhirExtractError
            raise FhirExtractError(err["error"])
        return err


def get_allergy_reaction(
    allergy: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get allergy reaction(s)."""
    try:
        if allergy is None or (isinstance(allergy, str) and allergy.strip() == ""):
            err = _error("empty_input", "No input provided")
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(err["error"])
            return err

        resource = _parse_resource(allergy, "AllergyIntolerance")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        reactions = []
        for r in getattr(resource, "reaction", None) or []:
            manifest = [format_codeable_concept(m) for m in (getattr(r, "manifestation", None) or [])]
            reactions.append({"manifestation": manifest, "severity": str(getattr(r, "severity", None)) if getattr(r, "severity", None) else None})

        result = {"success": True, "data": reactions}
        if raise_on_error:
            return result["data"]
        return result

    except Exception as e:
        err = _error("unexpected_error", str(e), details=repr(e))
        if raise_on_error:
            from fhir_agent_tools._parse import FhirExtractError
            raise FhirExtractError(err["error"])
        return err


def get_allergy_criticality(
    allergy: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get allergy criticality (low, high, unable-to-assess)."""
    try:
        if allergy is None or (isinstance(allergy, str) and allergy.strip() == ""):
            err = _error("empty_input", "No input provided")
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(err["error"])
            return err

        resource = _parse_resource(allergy, "AllergyIntolerance")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        criticality = str(getattr(resource, "criticality", None)) if getattr(resource, "criticality", None) else None
        result = {"success": True, "data": criticality}
        if raise_on_error:
            return result["data"]
        return result

    except Exception as e:
        err = _error("unexpected_error", str(e), details=repr(e))
        if raise_on_error:
            from fhir_agent_tools._parse import FhirExtractError
            raise FhirExtractError(err["error"])
        return err
