from decimal import Decimal
from enum import Enum
from typing import TYPE_CHECKING, Optional

from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
from core.database import Base
from sqlalchemy import (
    ForeignKeyConstraint,
    Index,
    Integer,
    Numeric,
    PrimaryKeyConstraint,
    String,
    Text,
    UniqueConstraint,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship

if TYPE_CHECKING:
    from api.v1.modules.a76.pedmientos.models.pedimento_config_additional import (
        PedimentoConfigAdditional,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_config_calculations import (
        PedimentoConfigCalculations,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_config_parameters import (
        PedimentoConfigParameters,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_config_surcharges import (
        PedimentoConfigSurcharges,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_config_update_rectification import (
        PedimentoConfigUpdateRectification,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_config_updates import (
        PedimentoConfigUpdates,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_containers import (
        PedimentoContainers,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_customs_offices import (
        PedimentoCustomsOffices,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_dates import PedimentoDates
    from api.v1.modules.a76.pedmientos.models.pedimento_decrementables import (
        PedimentoDecrementables,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_incrementables import (
        PedimentoIncrementables,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_indexes import PedimentoIndexes
    from api.v1.modules.a76.pedmientos.models.pedimento_packages import (
        PedimentoPackages,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_guides import (
        PedimentoGuides,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_contributions import (
        PedimentoContributions,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_payments import (
        PedimentoPayments,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_rectification_destination import (
        PedimentoRectificationDestination,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_rectification_origin import (
        PedimentoRectificationOrigin,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_seals import (
        PedimentoSeals,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_transport_carriers import (
        PedimentoTransportCarriers,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_transport_means import (
        PedimentoTransportMeans,
    )
    from api.v1.modules.a76.pedmientos.models.pedimento_validation import (
        PedimentoValidation,
    )


class PedimentoType(str, Enum):
    NORMAL = "normal"
    CONSOLIDATED = "consolidated"
    COMPLEMENTARY = "complementary"
    AUTOMOBILE = "automobile"

class OperationType(str, Enum):
    IMP = "imp"  # Importación
    EXP = "exp"  # Exportación


class Pedimentos(Base, TenantScopedMixin, TimestampMixin):
    __tablename__ = "pedimentos"
    __table_args__ = (
        PrimaryKeyConstraint("id", name="pedimentos_pkey"),
        ForeignKeyConstraint(
            ["client_id"], ["a76.clients_and_providers.id"], name="fk_pedimentos_client"
        ),
        ForeignKeyConstraint(
            ["regime"], ["public.pedimento_regimens.code"], name="fk_pedimentos_regime"
        ),
        ForeignKeyConstraint(
            ["pedimento_code"],
            ["public.pedimento_codes.code"],
            name="fk_pedimentos_code",
        ),
        UniqueConstraint(
            "tenant_id",
            "company_id",
            "year",
            "customs_office",
            "license",
            "pedimento_number",
            name="pedimentos_unique_key",
        ),
        Index("idx_pedimentos_client_id", "client_id"),
        Index("idx_pedimentos_created_at", "created_at"),
        Index("idx_pedimentos_status", "status"),
        {"schema": "a76"},
    )

    id: Mapped[int] = mapped_column(Integer)

    year: Mapped[str] = mapped_column(String(2))
    customs_office: Mapped[str] = mapped_column(String(3))
    license: Mapped[str] = mapped_column(String(4))
    pedimento_number: Mapped[str] = mapped_column(String(7))
    client_id: Mapped[Optional[int]] = mapped_column(
        Integer, nullable=True
    )  # Opcional: no requerido para el pedimento
    operation_type: Mapped[OperationType] = mapped_column(String(3))
    pedimento_type: Mapped[PedimentoType] = mapped_column(String(20))
    pedimento_code: Mapped[str] = mapped_column(String(2))
    regime: Mapped[str] = mapped_column(String(3))
    status: Mapped[Optional[str]] = mapped_column(String(30))
    usd_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(17, 6))
    paid_price: Mapped[Optional[Decimal]] = mapped_column(Numeric(17, 6))
    gross_weight: Mapped[Optional[Decimal]] = mapped_column(Numeric(19, 3))
    exchange_rate: Mapped[Optional[Decimal]] = mapped_column(Numeric(9, 5))
    observations: Mapped[Optional[str]] = mapped_column(Text)

    pedimento_config_additional: Mapped["PedimentoConfigAdditional"] = relationship(
        "PedimentoConfigAdditional",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_config_calculations: Mapped["PedimentoConfigCalculations"] = relationship(
        "PedimentoConfigCalculations",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_config_parameters: Mapped["PedimentoConfigParameters"] = relationship(
        "PedimentoConfigParameters",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_config_surcharges: Mapped["PedimentoConfigSurcharges"] = relationship(
        "PedimentoConfigSurcharges",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_config_update_rectification: Mapped[
        "PedimentoConfigUpdateRectification"
    ] = relationship(
        "PedimentoConfigUpdateRectification",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_config_updates: Mapped["PedimentoConfigUpdates"] = relationship(
        "PedimentoConfigUpdates",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_customs_offices: Mapped["PedimentoCustomsOffices"] = relationship(
        "PedimentoCustomsOffices",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_dates: Mapped["PedimentoDates"] = relationship(
        "PedimentoDates",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
        lazy="joined",
    )
    pedimento_decrementables: Mapped["PedimentoDecrementables"] = relationship(
        "PedimentoDecrementables",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_incrementables: Mapped["PedimentoIncrementables"] = relationship(
        "PedimentoIncrementables",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_indexes: Mapped["PedimentoIndexes"] = relationship(
        "PedimentoIndexes",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_payments: Mapped["PedimentoPayments"] = relationship(
        "PedimentoPayments",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_rectification_destination: Mapped["PedimentoRectificationDestination"] = (
        relationship(
            "PedimentoRectificationDestination",
            uselist=False,
            back_populates="pedimento",
            cascade="all, delete-orphan",
        )
    )
    pedimento_rectification_origin: Mapped["PedimentoRectificationOrigin"] = (
        relationship(
            "PedimentoRectificationOrigin",
            uselist=False,
            back_populates="pedimento",
            cascade="all, delete-orphan",
        )
    )
    pedimento_transport_means: Mapped["PedimentoTransportMeans"] = relationship(
        "PedimentoTransportMeans",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_validation: Mapped["PedimentoValidation"] = relationship(
        "PedimentoValidation",
        uselist=False,
        back_populates="pedimento",
        cascade="all, delete-orphan",
    )
    pedimento_packages: Mapped["PedimentoPackages"] = relationship(
        "PedimentoPackages", uselist=False, back_populates="pedimento", cascade="all, delete-orphan"
    )
    pedimento_transport_carriers: Mapped[list["PedimentoTransportCarriers"]] = relationship(
        "PedimentoTransportCarriers", back_populates="pedimento", cascade="all, delete-orphan"
    )
    pedimento_guides: Mapped[list["PedimentoGuides"]] = relationship(
        "PedimentoGuides", back_populates="pedimento", cascade="all, delete-orphan"
    )
    pedimento_contributions: Mapped[list["PedimentoContributions"]] = relationship(
        "PedimentoContributions", back_populates="pedimento", cascade="all, delete-orphan"
    )
    pedimento_seals: Mapped[list["PedimentoSeals"]] = relationship(
        "PedimentoSeals", back_populates="pedimento", cascade="all, delete-orphan"
    )
    pedimento_containers: Mapped[list["PedimentoContainers"]] = relationship(
        "PedimentoContainers", back_populates="pedimento", cascade="all, delete-orphan"
    )
