"""Extract data from FHIR Observation 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_period, format_reference


def _get_observation_value(resource: Any) -> Any:
    """Extract value from Observation - handles valueQuantity, valueString, etc."""
    for attr in ("valueQuantity", "valueString", "valueBoolean", "valueInteger", "valueDateTime"):
        val = getattr(resource, attr, None)
        if val is not None:
            if hasattr(val, "value"):
                return getattr(val, "value")
            return val
    val = getattr(resource, "valueCodeableConcept", None)
    if val is not None:
        return format_codeable_concept(val)
    return None


def get_observation_summary(
    observation: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Extract key Observation fields for LLM consumption."""
    try:
        if observation is None or (isinstance(observation, str) and observation.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(observation, "Observation")
        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),
            "code": format_codeable_concept(getattr(resource, "code", None)),
            "value": _get_observation_value(resource),
            "effective": _format_effective(resource),
            "status": str(getattr(resource, "status", None)) if getattr(resource, "status", None) else None,
            "subject": format_reference(getattr(resource, "subject", 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 _format_effective(resource: Any) -> str | None:
    """Format effectiveDateTime or effectivePeriod."""
    dt = getattr(resource, "effectiveDateTime", None)
    if dt is not None:
        return str(dt)
    period = getattr(resource, "effectivePeriod", None)
    if period is not None:
        return format_period(period)
    return None


def get_observation_value(
    observation: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get observation value (numeric, string, or codeable concept)."""
    try:
        if observation is None or (isinstance(observation, str) and observation.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(observation, "Observation")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        val = _get_observation_value(resource)
        result = {"success": True, "data": val}
        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_observation_code(
    observation: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get observation code (e.g., LOINC)."""
    try:
        if observation is None or (isinstance(observation, str) and observation.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(observation, "Observation")
        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_observation_effective(
    observation: str | dict | Any,
    *,
    raise_on_error: bool = False,
) -> dict[str, Any]:
    """Get observation effective date/time or period."""
    try:
        if observation is None or (isinstance(observation, str) and observation.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(observation, "Observation")
        if isinstance(resource, dict):
            if raise_on_error:
                from fhir_agent_tools._parse import FhirExtractError
                raise FhirExtractError(resource["error"])
            return resource

        effective = _format_effective(resource)
        result = {"success": True, "data": effective}
        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
