"""Modelos del módulo Tarifario (base de costos para Cotizaciones).

Un ``RateSheet`` (tarifario) pertenece a un proveedor y agrupa muchas
``RateLane`` (rutas origen→destino). Cada ruta tiene, según el modo:
- Aéreo / LCL: varios ``RateBreak`` (quiebres de peso/volumen con su tarifa).
- FCL / terrestre: una tarifa plana por contenedor/unidad (``flat_rate``).
Los ``RateCharge`` son cargos adicionales a nivel tarifario o ruta.
"""

from datetime import date
from decimal import Decimal

from sqlalchemy import Date, ForeignKey, Integer, Numeric, String, Text, text
from sqlalchemy.orm import Mapped, mapped_column

from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
from core.database import Base


class RateSheet(Base, TenantScopedMixin, TimestampMixin):
    __tablename__ = "rate_sheets"
    __table_args__ = {"schema": "crm"}

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    supplier_id: Mapped[int | None] = mapped_column(
        Integer, ForeignKey("crm.suppliers.id"), nullable=True, index=True
    )
    # aereo | maritimo_fcl | maritimo_lcl | terrestre
    mode: Mapped[str] = mapped_column(String(20), nullable=False, index=True)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    currency: Mapped[str | None] = mapped_column(String(3), nullable=True, server_default=text("'USD'"))
    valid_from: Mapped[date | None] = mapped_column(Date, nullable=True)
    valid_to: Mapped[date | None] = mapped_column(Date, nullable=True)
    default_origin: Mapped[str | None] = mapped_column(String(20), nullable=True)
    # borrador | activo | vencido | reemplazado
    status: Mapped[str] = mapped_column(String(20), nullable=False, server_default=text("'borrador'"))
    source_file: Mapped[str | None] = mapped_column(String(512), nullable=True)
    source_url: Mapped[str | None] = mapped_column(String(1024), nullable=True)
    notes: Mapped[str | None] = mapped_column(Text, nullable=True)
    created_by: Mapped[str | None] = mapped_column(String(64), nullable=True)
    updated_by: Mapped[str | None] = mapped_column(String(64), nullable=True)


class RateLane(Base, TenantScopedMixin, TimestampMixin):
    __tablename__ = "rate_lanes"
    __table_args__ = {"schema": "crm"}

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    rate_sheet_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("crm.rate_sheets.id"), nullable=False, index=True
    )
    origin: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True)
    destination: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True)
    region: Mapped[str | None] = mapped_column(String(60), nullable=True)
    # Solo FCL/terrestre (código del catálogo tipo_equipo). Nulo en aéreo/LCL.
    equipment_type: Mapped[str | None] = mapped_column(String(20), nullable=True)
    # per_kg | per_wm | per_container | flat
    rate_unit: Mapped[str | None] = mapped_column(String(20), nullable=True)
    min_charge: Mapped[Decimal | None] = mapped_column(Numeric(14, 4), nullable=True)
    flat_rate: Mapped[Decimal | None] = mapped_column(Numeric(14, 4), nullable=True)
    transit_days: Mapped[int | None] = mapped_column(Integer, nullable=True)
    notes: Mapped[str | None] = mapped_column(Text, nullable=True)


class RateBreak(Base, TenantScopedMixin, TimestampMixin):
    __tablename__ = "rate_breaks"
    __table_args__ = {"schema": "crm"}

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    rate_lane_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("crm.rate_lanes.id"), nullable=False, index=True
    )
    # Umbral del quiebre (kg en aéreo; W/M en LCL)
    from_qty: Mapped[Decimal] = mapped_column(Numeric(12, 3), nullable=False, server_default=text("0"))
    rate: Mapped[Decimal] = mapped_column(Numeric(14, 4), nullable=False, server_default=text("0"))


class RateCharge(Base, TenantScopedMixin, TimestampMixin):
    __tablename__ = "rate_charges"
    __table_args__ = {"schema": "crm"}

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    rate_sheet_id: Mapped[int | None] = mapped_column(
        Integer, ForeignKey("crm.rate_sheets.id"), nullable=True, index=True
    )
    rate_lane_id: Mapped[int | None] = mapped_column(
        Integer, ForeignKey("crm.rate_lanes.id"), nullable=True, index=True
    )
    concept: Mapped[str] = mapped_column(String(60), nullable=False)
    # fijo | por_kg | por_guia | por_contenedor | porcentaje
    charge_type: Mapped[str] = mapped_column(String(20), nullable=False, server_default=text("'fijo'"))
    value: Mapped[Decimal | None] = mapped_column(Numeric(14, 4), nullable=True)
    condition: Mapped[str | None] = mapped_column(Text, nullable=True)
