"""Extract data from FHIR Patient 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_address,
    format_human_name,
    format_identifier,
    format_reference,
    format_telecom,
)


def get_patient_summary(
    patient: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Extract key Patient fields for LLM consumption.

    Returns {success, data} with id, name, birthDate, gender, identifiers,
    telecom, address, managingOrganization.
    """
    try:
        if patient is None or (isinstance(patient, str) and patient.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(patient, "Patient")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        data = {
            "id": getattr(resource, "id", None),
            "name": format_human_name(resource.name if hasattr(resource, "name") else None),
            "birthDate": str(resource.birthDate) if getattr(resource, "birthDate", None) else None,
            "gender": str(resource.gender) if getattr(resource, "gender", None) else None,
            "active": getattr(resource, "active", None),
            "identifiers": format_identifier(resource.identifier if hasattr(resource, "identifier") else None),
            "telecom": format_telecom(resource.telecom if hasattr(resource, "telecom") else None),
            "address": format_address(resource.address if hasattr(resource, "address") else None),
            "managingOrganization": format_reference(
                resource.managingOrganization if hasattr(resource, "managingOrganization") else None
            ),
        }

        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_patient_name(
    patient: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get formatted patient name (e.g., 'Chalmers, Peter James')."""
    try:
        if patient is None or (isinstance(patient, str) and patient.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(patient, "Patient")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        name = format_human_name(resource.name if hasattr(resource, "name") else None)
        result = {"success": True, "data": name}
        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_patient_identifiers(
    patient: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get patient identifiers with system, value, and type."""
    try:
        if patient is None or (isinstance(patient, str) and patient.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(patient, "Patient")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        identifiers = format_identifier(resource.identifier if hasattr(resource, "identifier") else None)
        result = {"success": True, "data": identifiers}
        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_patient_telecom(
    patient: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get patient telecom (phone, email, etc.)."""
    try:
        if patient is None or (isinstance(patient, str) and patient.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(patient, "Patient")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        telecom = format_telecom(resource.telecom if hasattr(resource, "telecom") else None)
        result = {"success": True, "data": telecom}
        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_patient_address(
    patient: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get patient address(es)."""
    try:
        if patient is None or (isinstance(patient, str) and patient.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(patient, "Patient")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        address = format_address(resource.address if hasattr(resource, "address") else None)
        result = {"success": True, "data": address}
        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
