from decimal import Decimal
from typing import Optional, TYPE_CHECKING
from sqlalchemy import String, Numeric, ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship
from core.database import Base

if TYPE_CHECKING:
    from ..models import LineItem
    
class FractionType:
    """Enumeration for fraction types"""
    GENERAL = "GENERAL"
    PROSEC = "PROSEC"
    ALADI = "ALADI"
    TLCS = "TLCS"

class LineCustom(Base):
    """
    Customs details for line items
    Consolidates all line-level data from Q and S tables
    """
    __tablename__ = "item_line_customs"
    __table_args__ = {
        "schema": "a76",
    }
    
    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    item_line_id: Mapped[int] = mapped_column(ForeignKey("a76.item_lines.id"))
    
    # Tariff/Customs Classifications
    fraction: Mapped[Optional[str]] = mapped_column(String(10))  # FRACCION / FRACCIONIMPO / FRACCIONEXPO
    fraction_type: Mapped[Optional[FractionType]] = mapped_column(String(7))  # TIPOFRACCION / TIPOFRACCIONIMPO / TIPOFRACCIONEXPO
    american_fraction: Mapped[Optional[str]] = mapped_column(String(16))  # FRACCIONAMERICANA
    alternate_fraction: Mapped[Optional[str]] = mapped_column(String(10))  # FRACCIONALTERNA
    reference_fraction: Mapped[Optional[str]] = mapped_column(String(10))  # FRACCIONREFERENCIA
    octave_fraction: Mapped[Optional[str]] = mapped_column(String(10))  # FRACCIONROCTAVA
    tlcan_fraction: Mapped[Optional[str]] = mapped_column(String(13))  # FRACCIONTLCAN
    extra_american_fraction: Mapped[Optional[str]] = mapped_column(String(16))  # FRACAMESELEXTRA
    garment_fraction: Mapped[Optional[str]] = mapped_column(String(19))  # FRACCIONDELAPRENDA/FRACCIONDELAPARTIDA
    
    # Ad Valorem
    advalorem: Mapped[Optional[str]] = mapped_column(String(10))  # ADVIMPO / ADVEXPO
    advalorem_numeric: Mapped[Optional[Decimal]] = mapped_column(Numeric(7, 2))  # ADVIMPONUM / ADVEXPONUM
    advalorem_american: Mapped[Optional[Decimal]] = mapped_column(Numeric(5, 2))  # ADVAME 
    advalorem_tlcan: Mapped[Optional[Decimal]] = mapped_column(Numeric(5, 2))  # ADVTLCAN
    
    # Rates
    rate: Mapped[Optional[str]] = mapped_column(String(10))  # TASAIM / TASAEX
    depreciation_rate: Mapped[Optional[Decimal]] = mapped_column(Numeric(5, 2))  # TASADEPRECIA
    
    # Origin/Destination
    origin_country: Mapped[Optional[str]] = mapped_column(String(3))  # PAISORIGEN
    destination_country: Mapped[Optional[str]] = mapped_column(String(3))  # PAISDESTINO
    optional_country: Mapped[Optional[str]] = mapped_column(String(3))  # PAISOPCIONAL
    origin_procedure: Mapped[Optional[str]] = mapped_column(String(3))  # PROCEDENCIA
    scrap_procedure: Mapped[Optional[str]] = mapped_column(String(3))  # PROCSCRAP
    
    # Sector
    sector: Mapped[Optional[str]] = mapped_column(String(8))  # SECTOR
    
    # Relationship (one-to-one)
    line: Mapped["LineItem"] = relationship(back_populates="customs")