"""Mouse anatomy"""
{% raw -%}
from pydantic import BaseModel, ConfigDict
import requests

from aind_data_schema_models.registries import Registry
{% endraw %}
"""Mouse anatomy"""


class MouseAnatomyModel(BaseModel):
    """Base model for mouse anatomy"""

    model_config = ConfigDict(frozen=True)
    name: str
    registry: Registry.ONE_OF
    registry_identifier: str


def search_emapa_exact_match(class_name):
    """Pull the exact name match from the EMAPA ontology

    Parameters
    ----------
    class_name : str
        Name of class

    Returns
    -------
    list

    Raises
    ------
    Exception
        OLS query failed on any status code other than 200
    """
    base_url = "https://www.ebi.ac.uk/ols/api/search"
    params = {
        "q": class_name,
        "ontology": "emapa",  # Specify the ontology
        "type": "class",      # Search for classes
    }
    response = requests.get(base_url, params=params)
    if response.status_code == 200:
        results = response.json()
        # Extract terms with exact label match
        exact_matches = [
            {
                "iri": entry["iri"],
                "label": entry["label"],
            }
            for entry in results.get("response", {}).get("docs", [])
            if entry["label"].lower() == class_name.lower()
        ]
        return exact_matches
    else:
        raise Exception(f"OLS query failed: {response.status_code}, {response.text}")


def get_emapa_id(class_name):
    """Get the EMAPA ID for a given class name

    Parameters
    ----------
    class_name : str

    Returns
    -------
    int
    """
    results = search_emapa_exact_match(class_name)

    if results:
        return results[0]['iri'].split('_')[1]
    else:
        return None


class MouseAnatomyMeta(type):
    """Meta class for MouseAnatomy groups
    """
    def __getattribute__(cls, name):
        """Custom get attribute function, validates anatomy names against external EMAPA registry

        Parameters
        ----------
        name : str
            Attribute name

        Raises
        ------
        ValueError
            Name not found in the EMAPA registry
        """

        # bypass
        if name.startswith("__"):
            return object.__getattribute__(cls, name)

        class_dict = object.__getattribute__(cls, "__dict__")

        if name in class_dict:
            original_name = super().__getattribute__(name)

            emapa_id = get_emapa_id(original_name)

            if emapa_id:
                return MouseAnatomyModel(
                    name=original_name,
                    registry=Registry.EMAPA,
                    registry_identifier=emapa_id,
                )
            else:
                raise ValueError(f"Could not find EMAPA ID for {original_name}")

        # second bypass for defined values
        return super().__getattribute__(name)


class MouseAnatomy(metaclass=MouseAnatomyMeta):
    """MouseAnatomicalStructure"""
{% for _, row in data.iterrows() %}
    {{ row['name'] | to_class_name | upper }} = "{{ row['name'] }}"
{%- endfor %}

class MouseEmgMuscles(metaclass=MouseAnatomyMeta):
    """EMG muscles"""

    DELTOID = "deltoid"
    PECTORALIS_MAJOR = "pectoralis major"
    TRICEPS_BRACHII = "triceps brachii"
    LATERAL_HEAD_OF_TRICEPS_BRACHII = "lateral head of triceps brachii"
    LONG_HEAD_OF_TRICEPS_BRACHII = "long head of triceps brachii"
    MEDIAL_HEAD_OF_TRICEPS_BRACHII = "medial head of triceps brachii"
    BICEPS_BRACHII = "biceps brachii"
    LONG_HEAD_OF_BICEPS_BRACHII = "long head of biceps brachii"
    SHORT_HEAD_OF_BICEPS_BRACHII = "short head of biceps brachii"
    TENDON_OF_BICEPS_BRACHII = "tendon of biceps brachii"
    PARS_SCAPULARIS_OF_DELTOID = "pars scapularis of deltoid"
    EXTENSOR_CARPI_RADIALIS_LONGUS = "extensor carpi radialis longus"
    EXTENSOR_DIGITORUM_COMMUNIS = "extensor digitorum communis"
    EXTENSOR_DIGITORUM_LATERALIS = "extensor digitorum lateralis"
    EXTENSOR_CARPI_ULNARIS = "extensor carpi ulnaris"
    FLEXOR_CARPI_RADIALIS = "flexor carpi radialis"
    FLEXOR_CARPI_ULNARIS = "flexor carpi ulnaris"
    FLEXOR_DIGITORUM_PROFUNDUS = "flexor digitorum profundus"


class MouseBodyParts(metaclass=MouseAnatomyMeta):
    """Body parts"""

    FORELIMB = "forelimb"
    HEAD = "head"
    HINDLIMB = "hindlimb"
    NECK = "neck"
    TAIL = "tail"
    TRUNK = "trunk"

class GroundWireLocations(metaclass=MouseAnatomyMeta):
    """Ground wire locations"""

    FORELIMB = "forelimb"
    HEAD = "head"
    HINDLIMB = "hindlimb"
    NECK = "neck"
    TAIL = "tail"
    TRUNK = "trunk"
    BRAIN = "brain"
    CRANIUM = "cranium"

class MouseBloodVessels(metaclass=MouseAnatomyMeta):
    """Blood vessels"""

    CAROTID_ARTERY = "carotid artery"
    JUGULAR_VEIN = "jugular vein"

class InjectionTargets(metaclass=MouseAnatomyMeta):
    """ Common injection targets """

    VENOUS_SINUS = "venous sinus"
    PERITONEAL_CAVITY = "peritoneal cavity"
