from fastapi.exceptions import HTTPException

from sqlalchemy import (
    UUID,
    String,
    text,
)
from sqlalchemy.orm import (
    Mapped,
    mapped_column,
)
from databases.sql_models.core_mixin import CrudCollection


class ApiEnumDropdown(CrudCollection):
    __tablename__ = "api_enum_dropdown"
    __exclude__fields__ = ["enum_class"]

    id: Mapped[int] = mapped_column(primary_key=True)
    uu_id: Mapped[str] = mapped_column(
        UUID, server_default=text("gen_random_uuid()"), index=True, unique=True
    )
    enum_class: Mapped[str] = mapped_column(
        String, nullable=False, comment="Enum Constant Name"
    )
    key: Mapped[str] = mapped_column(String, nullable=False, comment="Enum Key")
    value: Mapped[str] = mapped_column(String, nullable=False, comment="Enum Value")
    description: Mapped[str] = mapped_column(String, nullable=True)

    __table_args__ = ({"comment": "Enum objets that are linked to tables"},)

    @classmethod
    def get_by_uuid(cls, uuid: str):
        return cls.filter_by_one(system=True, uu_id=str(uuid)).data

    @classmethod
    def get_debit_search(cls, search_debit: str = None, search_uu_id: str = None):
        if search_uu_id:
            if search := cls.filter_one(
                cls.enum_class.in_(["DebitTypes"]),
                cls.uu_id == search_uu_id,
                system=True,
            ).data:
                return search
        elif search_debit:
            if search := cls.filter_one(
                cls.enum_class.in_(["DebitTypes"]), cls.key == search_debit, system=True
            ).data:
                return search
        return cls.filter_all(cls.enum_class.in_(["DebitTypes"]), system=True).data

    @classmethod
    def get_due_types(cls):
        if due_list := cls.filter_all(
            cls.enum_class == "BuildDuesTypes",
            cls.key.in_(["BDT-A", "BDT-D"]),
            system=True,
        ).data:
            return [due.uu_id.__str__() for due in due_list]
        raise HTTPException(
            status_code=404,
            detail="No dues types found",
        )

    @classmethod
    def due_type_search(cls, search_management: str = None, search_uu_id: str = None):
        if search_uu_id:
            if search := cls.filter_one(
                cls.enum_class.in_(["BuildDuesTypes"]),
                cls.uu_id == search_uu_id,
                system=True,
            ).data:
                return search
        elif search_management:
            if search := cls.filter_one(
                cls.enum_class.in_(["BuildDuesTypes"]),
                cls.key == search_management,
                system=True,
            ).data:
                return search
        return cls.filter_all(cls.enum_class.in_(["BuildDuesTypes"]), system=True).data

    def get_enum_dict(self):
        return {
            "uu_id": str(self.uu_id),
            "enum_class": self.enum_class,
            "key": self.key,
            "value": self.value,
            "description": self.description,
        }

    @classmethod
    def uuid_of_enum(cls, enum_class: str, key: str):
        return str(
            getattr(
                cls.filter_one(
                    cls.enum_class == enum_class, cls.key == key, system=True
                ).data,
                "uu_id",
                None,
            )
        )


ApiEnumDropdown.set_session(ApiEnumDropdown.__session__)
