from typing import Optional
from pydantic import BaseModel, Field
from datetime import datetime, date
from enum import Enum


class RangeType(str, Enum):
    """Date range type for filtering"""
    INVOICE_DATE = "FF"  # Filter by invoice date
    PAYMENT_DATE = "FP"  # Filter by payment date


class ReportType(str, Enum):
    """Report type"""
    NORMAL = "Normal"
    DETAILED = "Detallado"


class CurrencyType(str, Enum):
    """Currency type for calculations"""
    FOREIGN = "ME"  # Foreign currency (Moneda Extranjera)
    LOCAL = "MN"    # Local currency (Moneda Nacional)


class ExchangeRateType(str, Enum):
    """Exchange rate calculation type"""
    PAYMENT = "FP"  # Use payment date
    INVOICE = "FF"  # Use invoice date


class MovementTypeFilter(str, Enum):
    """Movement type filter for definitive imports"""
    COMEX = "COMEX"  # ProvImpoDefCR = 'P'
    IMPDF = "IMPDF"  # ProvImpoDefCR != 'P'
    ALL = "ALL"      # No filter


class DischargeFilter(str, Enum):
    """Discharge filter for repair imports"""
    DISCHARGED = "SiDes"  # RepPim.Descarga = 1
    NOT_DISCHARGED = "NoDes"  # RepPim.Descarga = 0
    ALL = "ALL"  # No filter


class ExportMovementType(str, Enum):
    """Export movement type filter"""
    AFIJO = "AFIJO"  # Fixed assets
    NODES = "NODES"  # No discharge
    SCRAP = "SCRAP"  # Scrap
    REEXP = "REEXP"  # Re-export
    DONAC = "DONAC"  # Donation
    VEMEX = "VEMEX"  # Sale to Mexico
    ALL = "ALL"      # All types


class AllMovementsFilter(BaseModel):
    """Filters for all movements query (all types combined)"""
    range_type: RangeType = Field(
        default=RangeType.INVOICE_DATE,
        description="Date range type: FF for invoice date, FP for payment date"
    )
    start_date: str = Field(
        ...,
        description="Start date in YYYYMMDD format or ISO format"
    )
    end_date: str = Field(
        ...,
        description="End date in YYYYMMDD format or ISO format"
    )
    include_cancelled: bool = Field(
        default=False,
        description="Include cancelled invoices (Estatus != 'AC')"
    )
    provider: Optional[str] = Field(
        default=None,
        description="Filter by provider code"
    )
    buyer: Optional[str] = Field(
        default=None,
        description="Filter by buyer code"
    )
    pedimento_code: Optional[str] = Field(
        default=None,
        description="Filter by pedimento code (ClavePed)"
    )
    report_type: ReportType = Field(
        default=ReportType.NORMAL,
        description="Report type: Normal (grouped by invoice) or Detailed (line by line)"
    )
    currency_type: CurrencyType = Field(
        default=CurrencyType.FOREIGN,
        description="Currency type for value calculations"
    )
    exchange_rate_type: ExchangeRateType = Field(
        default=ExchangeRateType.PAYMENT,
        description="Exchange rate calculation method"
    )
    is_shelter: bool = Field(
        default=False,
        description="Use shelter company logic"
    )
    operation_type: Optional[str] = Field(
        default=None,
        description="Filter by operation type: 'imp' for imports only, 'exp' for exports only, None for all"
    )
    send_email: bool = Field(
        default=False,
        description="Send report via email to current user"
    )
    
    # Granular movement selection
    import_temp: bool = Field(default=True, description="Include temporary imports (IMTEM)")
    import_def: bool = Field(default=True, description="Include definitive imports (IMPDF/COMEX)")
    import_rep: bool = Field(default=True, description="Include repair imports (IMPRE)")
    export_def: bool = Field(default=True, description="Include definitive exports")
    export_rep: bool = Field(default=True, description="Include repair exports")
    
    # Specific filters
    export_types: Optional[list[str]] = Field(
        default=None, 
        description="Specific export legacy codes to include (AFIJO, NODES, etc)"
    )
    discharge_filter: DischargeFilter = Field(
        default=DischargeFilter.ALL,
        description="Global discharge filter for repair movements"
    )


class ImportTemporaryFilter(BaseModel):
    """Filters for temporary import movements query"""
    range_type: RangeType = Field(
        default=RangeType.INVOICE_DATE,
        description="Date range type: FF for invoice date, FP for payment date"
    )
    start_date: str = Field(
        ...,
        description="Start date in YYYYMMDD format or ISO format"
    )
    end_date: str = Field(
        ...,
        description="End date in YYYYMMDD format or ISO format"
    )
    include_cancelled: bool = Field(
        default=False,
        description="Include cancelled invoices (Estatus != 'AC')"
    )
    provider: Optional[str] = Field(
        default=None,
        description="Filter by provider code"
    )
    buyer: Optional[str] = Field(
        default=None,
        description="Filter by buyer code"
    )
    pedimento_code: Optional[str] = Field(
        default=None,
        description="Filter by pedimento code (ClavePed)"
    )
    report_type: ReportType = Field(
        default=ReportType.NORMAL,
        description="Report type: Normal or Detailed"
    )
    currency_type: CurrencyType = Field(
        default=CurrencyType.FOREIGN,
        description="Currency type for value calculations"
    )
    exchange_rate_type: ExchangeRateType = Field(
        default=ExchangeRateType.PAYMENT,
        description="Exchange rate calculation method"
    )
    is_shelter: bool = Field(
        default=False,
        description="Use shelter company logic"
    )
    database_name: str = Field(
        ...,
        description="Legacy database name to query from"
    )
    send_email: bool = Field(
        default=False,
        description="Send report via email to current user"
    )


class ImportDefinitiveFilter(BaseModel):
    """Filters for definitive import movements query"""
    range_type: RangeType = Field(
        default=RangeType.INVOICE_DATE,
        description="Date range type: FF for invoice date, FP for payment date"
    )
    start_date: str = Field(
        ...,
        description="Start date in YYYYMMDD format or ISO format"
    )
    end_date: str = Field(
        ...,
        description="End date in YYYYMMDD format or ISO format"
    )
    include_cancelled: bool = Field(
        default=False,
        description="Include cancelled invoices (Estatus != 'AC')"
    )
    provider: Optional[str] = Field(
        default=None,
        description="Filter by provider code"
    )
    buyer: Optional[str] = Field(
        default=None,
        description="Filter by buyer code (VendidoA)"
    )
    pedimento_code: Optional[str] = Field(
        default=None,
        description="Filter by pedimento code (ClavePed)"
    )
    movement_type: MovementTypeFilter = Field(
        default=MovementTypeFilter.ALL,
        description="Movement type filter: COMEX, IMPDF, or ALL"
    )
    report_type: ReportType = Field(
        default=ReportType.NORMAL,
        description="Report type: Normal or Detailed"
    )
    currency_type: CurrencyType = Field(
        default=CurrencyType.FOREIGN,
        description="Currency type for value calculations"
    )
    exchange_rate_type: ExchangeRateType = Field(
        default=ExchangeRateType.PAYMENT,
        description="Exchange rate calculation method"
    )
    is_shelter: bool = Field(
        default=False,
        description="Use shelter company logic"
    )
    use_transport_method: bool = Field(
        default=False,
        description="Use MetTrans# = 1 logic for specific pedimento types"
    )
    database_name: str = Field(
        ...,
        description="Legacy database name to query from"
    )
    send_email: bool = Field(
        default=False,
        description="Send report via email to current user"
    )

class MovementItem(BaseModel):
    """Movement item representing a temporary import invoice"""
    Factura: Optional[str] = Field(None, description="Invoice number")
    Pedimento: Optional[str] = Field(None, description="Pedimento number")
    FechaFactura: Optional[datetime] = Field(None, description="Invoice date")
    Estatus: Optional[str] = Field(None, description="Status (AC=Active, etc)")
    ClavePed: Optional[str] = Field(None, description="Pedimento code")
    TipoMovTemDef: Optional[str] = Field(None, description="Movement type (IMTEM=Temporary Import)")
    EsCambioRegimen: Optional[str] = Field(None, description="Is regime change (S/N)")
    ValorMPTemp: Optional[float] = Field(None, description="Temporary raw material value")
    ValorComercialMN: Optional[float] = Field(None, description="Commercial value in MN")
    TipoCambio: Optional[float] = Field(None, description="Exchange rate used")
    ValorAgre: Optional[float] = Field(default=0.0, description="Aggregate value")
    TipoExpo: Optional[str] = Field(default='', description="Export type")
    PedimentoR1: Optional[str] = Field(None, description="Rectification pedimento")
    EDocument: Optional[str] = Field(None, description="Electronic document")
    NumOperacionVU: Optional[str] = Field(None, description="VU operation number")
    BaseDeDatos: Optional[str] = Field(None, description="Source database name")
    NumGafUni: Optional[str] = Field(None, description="Unique badge number (driver)")
    UsuarioCap: Optional[str] = Field(None, description="Capture user")
    UsuarioAcr: Optional[str] = Field(None, description="Update user")
    Fecha_Pago: Optional[datetime] = Field(None, description="Payment date")
    NumCaja: Optional[str] = Field(None, description="Box/Container number")
    Pedimento18: Optional[str] = Field(None, description="18-digit pedimento")
    AduanaCru: Optional[str] = Field(None, description="Crossing customs")
    Lote: Optional[str] = Field(None, description="Lot number")

    model_config = {
        "json_schema_extra": {
            "example": {
                "Factura": "F-2024-001",
                "Pedimento": "24  47  3807  8001234",
                "FechaFactura": "2024-01-15T00:00:00",
                "Estatus": "AC",
                "ClavePed": "IM",
                "TipoMovTemDef": "IMTEM",
                "ValorMPTemp": 10000.50,
                "TipoCambio": 17.25
            }
        }
    }


class ImportRepairFilter(BaseModel):
    """Filters for repair import movements query"""
    range_type: RangeType = Field(
        default=RangeType.INVOICE_DATE,
        description="Date range type: FF for invoice date, FP for payment date"
    )
    start_date: str = Field(
        ...,
        description="Start date in YYYYMMDD format or ISO format"
    )
    end_date: str = Field(
        ...,
        description="End date in YYYYMMDD format or ISO format"
    )
    include_cancelled: bool = Field(
        default=False,
        description="Include cancelled invoices (Estatus != 'AC')"
    )
    provider: Optional[str] = Field(
        default=None,
        description="Filter by provider code"
    )
    buyer: Optional[str] = Field(
        default=None,
        description="Filter by buyer code (VendidoA)"
    )
    pedimento_code: Optional[str] = Field(
        default=None,
        description="Filter by pedimento code (ClavePed)"
    )
    discharge_filter: DischargeFilter = Field(
        default=DischargeFilter.ALL,
        description="Discharge filter: SiDes (discharged), NoDes (not discharged), or ALL"
    )
    report_type: ReportType = Field(
        default=ReportType.NORMAL,
        description="Report type: Normal or Detailed"
    )
    currency_type: CurrencyType = Field(
        default=CurrencyType.FOREIGN,
        description="Currency type for value calculations"
    )
    exchange_rate_type: ExchangeRateType = Field(
        default=ExchangeRateType.PAYMENT,
        description="Exchange rate calculation method"
    )
    is_shelter: bool = Field(
        default=False,
        description="Use shelter company logic"
    )
    use_transport_method: bool = Field(
        default=False,
        description="Use MetTrans# = 1 logic for specific pedimento types"
    )
    database_name: str = Field(
        ...,
        description="Legacy database name to query from"
    )
    send_email: bool = Field(
        default=False,
        description="Send report via email to current user"
    )


class MovementItemDetailed(BaseModel):
    """Detailed movement item with all line-level information"""
    Linea: Optional[int] = Field(None, description="Line number")
    Factura: Optional[str] = Field(None, description="Invoice number")
    Pedimento: Optional[str] = Field(None, description="Pedimento number")
    FechaFactura: Optional[datetime] = Field(None, description="Invoice date")
    Estatus: Optional[str] = Field(None, description="Status (AC=Active, etc)")
    ClavePed: Optional[str] = Field(None, description="Pedimento code")
    TipoMovTemDef: Optional[str] = Field(None, description="Movement type")
    EsCambioRegimen: Optional[str] = Field(None, description="Is regime change (S/N)")
    Regimen: Optional[str] = Field(None, description="Regime")
    Fecha_Inicio: Optional[datetime] = Field(None, description="Start date")
    Fecha_Fin: Optional[datetime] = Field(None, description="End date")
    Fecha_Pago: Optional[datetime] = Field(None, description="Payment date")
    Remesa: Optional[str] = Field(None, description="Remesa")
    
    # Provider information
    Proveedor: Optional[str] = Field(None, description="Provider name")
    RFCProveedor: Optional[str] = Field(None, description="Provider RFC")
    ProveedorTaxID: Optional[str] = Field(None, description="Provider Tax ID")
    
    # Buyer information
    VendidoA: Optional[str] = Field(None, description="Buyer name")
    VendidoARFC: Optional[str] = Field(None, description="Buyer RFC")
    VendidoATaxID: Optional[str] = Field(None, description="Buyer Tax ID")
    
    # Customs broker
    AgenteAduanal: Optional[str] = Field(None, description="Customs broker name")
    Patente: Optional[str] = Field(None, description="Customs broker patent")
    
    # Item details
    NumParte: Optional[str] = Field(None, description="Part number")
    DescripcionE: Optional[str] = Field(None, description="Spanish description")
    DescripcionI: Optional[str] = Field(None, description="English description")
    CantidadIE: Optional[float] = Field(None, description="Quantity")
    UniMed: Optional[str] = Field(None, description="Unit of measure")
    ValorComercialMN: Optional[float] = Field(None, description="Commercial value in MN")
    TipoCambio: Optional[float] = Field(None, description="Exchange rate")
    PesoNeto: Optional[float] = Field(None, description="Net weight")
    PesoBruto: Optional[float] = Field(None, description="Gross weight")
    
    # Additional fields
    OrdenCompraVenta: Optional[str] = Field(None, description="Purchase order")
    FraccionArancelaria: Optional[str] = Field(None, description="Tariff fraction")
    Preferencia: Optional[str] = Field(None, description="Preference")
    Sector: Optional[str] = Field(None, description="Sector")
    PaisOrigen: Optional[str] = Field(None, description="Country of origin")
    Aduana: Optional[str] = Field(None, description="Customs office")
    Advalorem: Optional[str] = Field(None, description="Ad valorem")
    TipoExpo: Optional[str] = Field(default='', description="Export type")
    PedimentoR1: Optional[str] = Field(None, description="Rectification pedimento")
    EDocument: Optional[str] = Field(None, description="Electronic document")
    NumOperacionVU: Optional[str] = Field(None, description="VU operation number")
    
    # Series information
    Series: Optional[str] = Field(None, description="Serial numbers")
    Marca: Optional[str] = Field(None, description="Brand")
    Modelo: Optional[str] = Field(None, description="Model")
    FraccionAmericana: Optional[str] = Field(None, description="American tariff fraction")
    ECCN: Optional[str] = Field(None, description="ECCN code")
    SimboloEx: Optional[str] = Field(None, description="Export symbol/license")
    FechaEmision: Optional[datetime] = Field(None, description="Emission date")
    
    # Metadata
    BaseDeDatos: Optional[str] = Field(None, description="Source database")
    NumGafUni: Optional[str] = Field(None, description="Unique badge number")
    UsuarioCap: Optional[str] = Field(None, description="Capture user")
    UsuarioAcr: Optional[str] = Field(None, description="Update user")
    Transportista: Optional[str] = Field(None, description="Transporter")
    NumCaja: Optional[str] = Field(None, description="Box number")
    Pedimento18: Optional[str] = Field(None, description="18-digit pedimento")
    AduanaCru: Optional[str] = Field(None, description="Crossing customs")
    Lote: Optional[str] = Field(None, description="Lot number")

    model_config = {
        "json_schema_extra": {
            "example": {
                "Linea": 1
            }
        }
    }


class ExportFilter(BaseModel):
    """Filters for export movements query"""
    range_type: RangeType = Field(
        default=RangeType.INVOICE_DATE,
        description="Date range type: FF for invoice date, FP for payment date"
    )
    start_date: str = Field(
        ...,
        description="Start date in YYYYMMDD format or ISO format"
    )
    end_date: str = Field(
        ...,
        description="End date in YYYYMMDD format or ISO format"
    )
    include_cancelled: bool = Field(
        default=False,
        description="Include cancelled invoices (Estatus = 'NA')"
    )
    provider: Optional[str] = Field(
        None,
        description="Filter by provider code"
    )
    buyer: Optional[str] = Field(
        None,
        description="Filter by buyer code (VendidoA)"
    )
    pedimento_code: Optional[str] = Field(
        None,
        description="Filter by pedimento code (ClavePed)"
    )
    movement_type: ExportMovementType = Field(
        default=ExportMovementType.ALL,
        description="Filter by export movement type (AFIJO, NODES, SCRAP, REEXP, DONAC, VEMEX)"
    )
    discharge_filter: DischargeFilter = Field(
        default=DischargeFilter.ALL,
        description="Filter by discharge status: SiDes, NoDes, or ALL"
    )
    report_type: ReportType = Field(
        default=ReportType.NORMAL,
        description="Normal (grouped by invoice) or Detallado (line by line)"
    )
    currency_type: CurrencyType = Field(
        default=CurrencyType.FOREIGN,
        description="Currency type: ME (foreign) or MN (local)"
    )
    exchange_rate_type: ExchangeRateType = Field(
        default=ExchangeRateType.PAYMENT,
        description="Exchange rate type: FP (payment date) or FF (invoice date)"
    )
    is_shelter: bool = Field(
        default=False,
        description="Shelter company flag"
    )
    use_transport_method: bool = Field(
        default=False,
        description="Use transport method for exchange rate logic"
    )
    database_name: str = Field(
        ...,
        description="Legacy database name"
    )
    send_email: bool = Field(
        default=False,
        description="Send report via email to current user"
    )

    model_config = {
        "json_schema_extra": {
            "example": {
                "range_type": "FF",
                "start_date": "20240101",
                "end_date": "20240131",
                "include_cancelled": False,
                "provider": None,
                "buyer": None,
                "pedimento_code": None,
                "movement_type": "ALL",
                "discharge_filter": "ALL",
                "report_type": "Normal",
                "currency_type": "ME",
                "exchange_rate_type": "FP",
                "is_shelter": False,
                "use_transport_method": False,
                "database_name": "MYDB"
            }
        }
    }

class ExportRepairFilter(BaseModel):
    """Filters for export repair movements query (EXPO REP)"""
    range_type: RangeType = Field(
        default=RangeType.INVOICE_DATE,
        description="Date range type: FF for invoice date, FP for payment date"
    )
    start_date: str = Field(
        ...,
        description="Start date in YYYYMMDD format or ISO format"
    )
    end_date: str = Field(
        ...,
        description="End date in YYYYMMDD format or ISO format"
    )
    include_cancelled: bool = Field(
        default=False,
        description="Include cancelled invoices (Estatus = 'NA')"
    )
    provider: Optional[str] = Field(
        None,
        description="Filter by provider code"
    )
    buyer: Optional[str] = Field(
        None,
        description="Filter by buyer code (VendidoA)"
    )
    pedimento_code: Optional[str] = Field(
        None,
        description="Filter by pedimento code (ClavePed)"
    )
    movement_type: ExportMovementType = Field(
        default=ExportMovementType.ALL,
        description="Filter by movement type (AFIJO, NODES for repair exports)"
    )
    discharge_filter: DischargeFilter = Field(
        default=DischargeFilter.ALL,
        description="Filter by discharge status: SiDes, NoDes, or ALL"
    )
    report_type: ReportType = Field(
        default=ReportType.NORMAL,
        description="Normal (grouped by invoice) or Detallado (line by line)"
    )
    currency_type: CurrencyType = Field(
        default=CurrencyType.FOREIGN,
        description="Currency type: ME (foreign) or MN (local)"
    )
    exchange_rate_type: ExchangeRateType = Field(
        default=ExchangeRateType.PAYMENT,
        description="Exchange rate type: FP (payment date) or FF (invoice date)"
    )
    is_shelter: bool = Field(
        default=False,
        description="Shelter company flag"
    )
    database_name: str = Field(
        ...,
        description="Legacy database name"
    )
    send_email: bool = Field(
        default=False,
        description="Send report via email to current user"
    )

    model_config = {
        "json_schema_extra": {
            "example": {
                "range_type": "FF",
                "start_date": "20240101",
                "end_date": "20240131",
                "include_cancelled": False,
                "provider": None,
                "buyer": None,
                "pedimento_code": None,
                "movement_type": "ALL",
                "discharge_filter": "ALL",
                "report_type": "Normal",
                "currency_type": "ME",
                "exchange_rate_type": "FP",
                "is_shelter": False,
                "database_name": "MYDB"
            }
        }
    }