"""
DTOs (Data Transfer Objects) para módulo de empresa
Reemplaza schemas.py siguiendo enfoque DDD y estilo NestJS
"""

from datetime import date, datetime
from typing import Optional

from pydantic import BaseModel, ConfigDict, Field, field_validator


class CompanyCreateDTO(BaseModel):
    """DTO para crear una empresa"""

    name: Optional[str] = Field(None, max_length=255, description="Company name")
    rfc: Optional[str] = Field(None, max_length=30, description="Company RFC")
    main_activity: Optional[str] = Field(
        None, max_length=255, description="Main activity"
    )

    # Program information
    program: Optional[str] = Field(None, max_length=10, description="Program")
    program_number: Optional[str] = Field(
        None, max_length=40, description="Program number"
    )
    prosec: Optional[int] = Field(None, description="PROSEC")
    prosec_authorization: Optional[str] = Field(
        None, max_length=20, description="PROSEC authorization"
    )

    # Identifiers
    manufacturer_id: Optional[str] = Field(
        None, max_length=25, description="Manufacturer ID"
    )
    broker_company: Optional[str] = Field(
        None, max_length=10, description="Broker company"
    )

    # Responsible person
    responsible: Optional[str] = Field(
        None, max_length=80, description="Responsible person"
    )
    responsible_name: Optional[str] = Field(
        None, max_length=20, description="Responsible first name"
    )
    responsible_last_name: Optional[str] = Field(
        None, max_length=20, description="Responsible last name"
    )
    responsible_mother_last_name: Optional[str] = Field(
        None, max_length=20, description="Responsible mother's last name"
    )
    responsible_rfc: Optional[str] = Field(
        None, max_length=30, description="Responsible RFC"
    )
    position: Optional[str] = Field(
        None, max_length=30, description="Responsible position"
    )

    # Configuration
    logo: Optional[str] = Field(None, max_length=512, description="Company logo (path local o clave S3)")
    order_format_type: Optional[str] = Field(
        None, max_length=19, description="Order format type"
    )
    previous_code: Optional[int] = Field(None, description="Previous code")
    is_service_company: Optional[bool] = Field(None, description="Is service company")
    fiscal_deposit: Optional[bool] = Field(None, description="Fiscal deposit")
    generate_barcodes_with_fiel: Optional[bool] = Field(None, description="Generate barcodes with FIEL")

    # Client and subassembly
    client_name: Optional[str] = Field(None, max_length=300, description="Client name")
    subassembly_mode: Optional[str] = Field(
        None, max_length=7, description="Subassembly mode"
    )

    # Additional information
    curp: Optional[str] = Field(None, max_length=19, description="CURP")
    inter_db_name: Optional[str] = Field(
        None, max_length=100, description="Inter DB name"
    )
    ctpat_svi: Optional[str] = Field(None, max_length=100, description="CTPAT SVI")
    trusted_exporter_number: Optional[str] = Field(
        None, max_length=50, description="Trusted exporter number"
    )
    prevalidator_key: Optional[str] = Field(
        None, max_length=20, description="Prevalidator key"
    )
    seventh_amendment: Optional[bool] = Field(None, description="Seventh amendment")

    # Sectors
    sector1: Optional[str] = Field(None, max_length=150)
    sector2: Optional[str] = Field(None, max_length=150)
    sector3: Optional[str] = Field(None, max_length=5)

    # Certification (CompanyCertification flattened)
    is_certified_company: Optional[bool] = None
    certified_company_registration: Optional[str] = Field(None, max_length=40)
    certified_company_start_date: Optional[date] = None
    certified_company_end_date: Optional[date] = None
    annex30_certification_date: Optional[date] = None
    annex30_certification_number: Optional[str] = Field(None, max_length=50)
    annex30_modality: Optional[str] = Field(None, max_length=3)
    annex30_company_type: Optional[str] = Field(None, max_length=50)
    annex30_renewal_date: Optional[date] = None
    annex30_final_certification_date: Optional[date] = None
    is_oea_company: Optional[bool] = None
    neec_company: Optional[bool] = None
    is_seciit_company: Optional[bool] = None

    # Addresses (Flattened)
    # Main
    main_street: Optional[str] = Field(None, max_length=100)
    main_exterior_number: Optional[str] = Field(None, max_length=10)
    main_interior_number: Optional[str] = Field(None, max_length=10)
    main_postal_code: Optional[str] = Field(None, max_length=5)
    main_neighborhood: Optional[str] = Field(None, max_length=40)
    main_city: Optional[str] = Field(None, max_length=40)
    main_municipality: Optional[str] = Field(None, max_length=50)
    main_state: Optional[str] = Field(None, max_length=30)
    main_country: Optional[str] = Field(None, max_length=4)
    main_phone: Optional[str] = Field(None, max_length=20)
    main_fax: Optional[str] = Field(None, max_length=20)
    main_email: Optional[str] = Field(None, max_length=100)
    # Industrial 1
    ind1_street: Optional[str] = Field(None, max_length=100)
    ind1_exterior_number: Optional[str] = Field(None, max_length=10)
    ind1_interior_number: Optional[str] = Field(None, max_length=10)
    ind1_postal_code: Optional[str] = Field(None, max_length=5)
    ind1_neighborhood: Optional[str] = Field(None, max_length=40)
    ind1_city: Optional[str] = Field(None, max_length=40)
    ind1_municipality: Optional[str] = Field(None, max_length=50)
    ind1_state: Optional[str] = Field(None, max_length=30)
    ind1_country: Optional[str] = Field(None, max_length=4)
    ind1_phone: Optional[str] = Field(None, max_length=20)
    ind1_fax: Optional[str] = Field(None, max_length=20)
    ind1_email: Optional[str] = Field(None, max_length=100)
    # Industrial 2
    ind2_street: Optional[str] = Field(None, max_length=100)
    ind2_exterior_number: Optional[str] = Field(None, max_length=10)
    ind2_interior_number: Optional[str] = Field(None, max_length=10)
    ind2_postal_code: Optional[str] = Field(None, max_length=5)
    ind2_neighborhood: Optional[str] = Field(None, max_length=40)
    ind2_city: Optional[str] = Field(None, max_length=40)
    ind2_municipality: Optional[str] = Field(None, max_length=50)
    ind2_state: Optional[str] = Field(None, max_length=30)
    ind2_country: Optional[str] = Field(None, max_length=4)
    ind2_phone: Optional[str] = Field(None, max_length=20)
    ind2_fax: Optional[str] = Field(None, max_length=20)
    ind2_email: Optional[str] = Field(None, max_length=100)

    # Technical flags
    active_labels: Optional[int] = None
    active_fractions: Optional[int] = None
    activate_caat: Optional[int] = None
    trans_interface: Optional[int] = None
    american_costs: Optional[int] = None
    scaf_readonly: Optional[int] = None
    parts_replacement: Optional[int] = None
    activate_facmexame: Optional[int] = None
    part_reference: Optional[int] = None
    international_firm: Optional[int] = None

    # Advanced Config
    ftp_key: Optional[str] = Field(None, max_length=10)
    sifra_path: Optional[str] = Field(None, max_length=255)
    version_type: Optional[str] = Field(None, max_length=20)
    sql_language: Optional[str] = Field(None, max_length=19)
    balance_operation_mode: Optional[str] = Field(None, max_length=50)

    # Prevalidator (detailed)
    prev_customs: Optional[str] = Field(None, max_length=20)
    prev_key: Optional[str] = Field(None, max_length=20)
    prev_patent: Optional[str] = Field(None, max_length=4)
    prev_description: Optional[str] = Field(None, max_length=100)

    # Ventanilla Única (VU)
    vu_webservice_user: Optional[str] = Field(None, max_length=100)
    vu_webservice_password: Optional[str] = Field(None, max_length=100)
    vu_email: Optional[str] = Field(None, max_length=800)
    vu_figure_type: Optional[str] = Field(None, max_length=29)
    vu_central_path: Optional[str] = Field(None, max_length=1499)
    vu_xml_files_path: Optional[str] = Field(None, max_length=1499)
    vu_query_rfc: Optional[str] = Field(None, max_length=30)
    vu_validation_rfc: Optional[str] = Field(None, max_length=30)
    vu_configuration_source: Optional[str] = Field(None, max_length=30)
    vu_measurement_units: Optional[str] = Field(None, max_length=3)

    # Electronic Agent
    ea_input_folder: Optional[str] = Field(None, max_length=1000)
    ea_output_folder: Optional[str] = Field(None, max_length=1000)
    ea_send_mask: Optional[str] = Field(None, max_length=20)
    ea_response_mask: Optional[str] = Field(None, max_length=20)
    ea_response_extension: Optional[str] = Field(None, max_length=20)
    ea_counter_start: Optional[int] = None
    ea_counter_end: Optional[int] = None
    ea_counter_next: Optional[int] = None

    # CFDI
    cfdi_xml_save_path: Optional[str] = Field(None, max_length=5000)
    cfdi_app_path: Optional[str] = Field(None, max_length=5000)
    cfdi_pac_app_path: Optional[str] = Field(None, max_length=5000)

    # Digital Certificates (CompanyDigitalCertificate flattened)
    # FIEL
    fiel_cer: Optional[str] = Field(None, max_length=5000)
    fiel_key: Optional[str] = Field(None, max_length=5000)
    fiel_pass: Optional[str] = Field(None, max_length=200)
    fiel_access: Optional[str] = Field(None, max_length=50)
    fiel_cer_exp: Optional[int] = None
    fiel_key_exp: Optional[int] = None
    # CFDI (Sello)
    cfdi_cert_cer: Optional[str] = Field(None, max_length=5000)
    cfdi_cert_key: Optional[str] = Field(None, max_length=5000)
    cfdi_cert_pass: Optional[str] = Field(None, max_length=200)
    cfdi_cert_access: Optional[str] = Field(None, max_length=50)
    cfdi_cert_cer_exp: Optional[int] = None
    cfdi_cert_key_exp: Optional[int] = None
    # Cancellation
    cancel_cer: Optional[str] = Field(None, max_length=5000)
    cancel_key: Optional[str] = Field(None, max_length=5000)
    cancel_pass: Optional[str] = Field(None, max_length=200)
    cancel_access: Optional[str] = Field(None, max_length=50)
    cancel_cer_exp: Optional[int] = None
    cancel_key_exp: Optional[int] = None


    model_config = ConfigDict(from_attributes=True)

    @field_validator(
        "certified_company_start_date",
        "certified_company_end_date",
        "annex30_certification_date",
        "annex30_renewal_date",
        "annex30_final_certification_date",
        mode="before",
    )
    @classmethod
    def validate_dates(cls, value):
        """Acepta exclusivamente DD/MM/YYYY para payload string."""
        if value in (None, ""):
            return None
        if isinstance(value, date):
            return value
        if isinstance(value, str):
            try:
                return datetime.strptime(value, "%d/%m/%Y").date()
            except ValueError as exc:
                raise ValueError("Date must be in DD/MM/YYYY format") from exc
        raise ValueError("Date must be in DD/MM/YYYY format")

    @field_validator("annex30_modality", mode="before")
    @classmethod
    def validate_annex30_modality(cls, value):
        if value in (None, ""):
            return None
        normalized = str(value).strip().upper()
        if normalized not in {"A", "AA", "AAA"}:
            raise ValueError("Annex 30 modality must be one of: A, AA, AAA")
        return normalized


class CompanyUpdateDTO(CompanyCreateDTO):
    """DTO para actualizar una empresa"""
    pass


class CompanyResponseDTO(BaseModel):
    """DTO para respuesta de empresa"""

    id: int
    tenant_id: int
    name: Optional[str] = None
    rfc: Optional[str] = None
    main_activity: Optional[str] = None

    # Program information
    program: Optional[str] = None
    program_number: Optional[str] = None
    prosec: Optional[int] = None
    prosec_authorization: Optional[str] = None

    # Identifiers
    manufacturer_id: Optional[str] = None
    broker_company: Optional[str] = None

    # Responsible person
    responsible: Optional[str] = None
    responsible_name: Optional[str] = None
    responsible_last_name: Optional[str] = None
    responsible_mother_last_name: Optional[str] = None
    responsible_rfc: Optional[str] = None
    position: Optional[str] = None

    # Configuration
    logo: Optional[str] = None
    fiscal_deposit: Optional[bool] = None
    generate_barcodes_with_fiel: Optional[bool] = None
    order_format_type: Optional[str] = None
    previous_code: Optional[int] = None
    is_service_company: Optional[bool] = None

    # Client and subassembly
    client_name: Optional[str] = None
    subassembly_mode: Optional[str] = None

    # Additional information
    curp: Optional[str] = None
    inter_db_name: Optional[str] = None
    ctpat_svi: Optional[str] = None
    trusted_exporter_number: Optional[str] = None
    prevalidator_key: Optional[str] = None
    seventh_amendment: Optional[bool] = None

    # Timestamps
    created_at: datetime
    updated_at: Optional[datetime] = None

    # --- Flattened Fields for Response ---
    # Sectores
    sector1: Optional[str] = None
    sector2: Optional[str] = None
    sector3: Optional[str] = None

    # Certification
    is_certified_company: Optional[bool] = None
    certified_company_registration: Optional[str] = None
    certified_company_start_date: Optional[date] = None
    certified_company_end_date: Optional[date] = None
    annex30_certification_date: Optional[date] = None
    annex30_certification_number: Optional[str] = None
    annex30_modality: Optional[str] = None
    annex30_company_type: Optional[str] = None
    annex30_renewal_date: Optional[date] = None
    annex30_final_certification_date: Optional[date] = None
    is_seciit_company: Optional[bool] = None
    is_oea_company: Optional[bool] = None
    neec_company: Optional[bool] = None

    # Addresses
    # ... (Main, Ind1, Ind2 can be added here if needed for flattened response)
    main_street: Optional[str] = None
    main_exterior_number: Optional[str] = None
    main_interior_number: Optional[str] = None
    main_postal_code: Optional[str] = None
    main_neighborhood: Optional[str] = None
    main_city: Optional[str] = None
    main_municipality: Optional[str] = None
    main_state: Optional[str] = None
    main_country: Optional[str] = None
    main_phone: Optional[str] = None
    main_fax: Optional[str] = None
    main_email: Optional[str] = None

    ind1_street: Optional[str] = None
    ind1_exterior_number: Optional[str] = None
    ind1_interior_number: Optional[str] = None
    ind1_postal_code: Optional[str] = None
    ind1_neighborhood: Optional[str] = None
    ind1_city: Optional[str] = None
    ind1_municipality: Optional[str] = None
    ind1_state: Optional[str] = None
    ind1_country: Optional[str] = None
    ind1_phone: Optional[str] = None
    ind1_fax: Optional[str] = None
    ind1_email: Optional[str] = None

    ind2_street: Optional[str] = None
    ind2_exterior_number: Optional[str] = None
    ind2_interior_number: Optional[str] = None
    ind2_postal_code: Optional[str] = None
    ind2_neighborhood: Optional[str] = None
    ind2_city: Optional[str] = None
    ind2_municipality: Optional[str] = None
    ind2_state: Optional[str] = None
    ind2_country: Optional[str] = None
    ind2_phone: Optional[str] = None
    ind2_fax: Optional[str] = None
    ind2_email: Optional[str] = None

    # Technical flags
    active_labels: Optional[int] = None
    active_fractions: Optional[int] = None
    activate_caat: Optional[int] = None
    trans_interface: Optional[int] = None
    american_costs: Optional[int] = None
    scaf_readonly: Optional[int] = None
    parts_replacement: Optional[int] = None
    activate_facmexame: Optional[int] = None
    part_reference: Optional[int] = None
    international_firm: Optional[int] = None

    # Advanced Config
    ftp_key: Optional[str] = None
    sifra_path: Optional[str] = None
    version_type: Optional[str] = None
    sql_language: Optional[str] = None
    balance_operation_mode: Optional[str] = None

    # Prevalidator
    prev_customs: Optional[str] = None
    prev_key: Optional[str] = None
    prev_patent: Optional[str] = None
    prev_description: Optional[str] = None

    # VU
    vu_webservice_user: Optional[str] = None
    vu_webservice_password: Optional[str] = None
    vu_email: Optional[str] = None
    vu_figure_type: Optional[str] = None
    vu_central_path: Optional[str] = None
    vu_xml_files_path: Optional[str] = None
    vu_query_rfc: Optional[str] = None
    vu_validation_rfc: Optional[str] = None
    vu_configuration_source: Optional[str] = None
    vu_measurement_units: Optional[str] = None

    # Electronic Agent
    ea_input_folder: Optional[str] = None
    ea_output_folder: Optional[str] = None
    ea_send_mask: Optional[str] = None
    ea_response_mask: Optional[str] = None
    ea_response_extension: Optional[str] = None
    ea_counter_start: Optional[int] = None
    ea_counter_end: Optional[int] = None
    ea_counter_next: Optional[int] = None

    # CFDI
    cfdi_xml_save_path: Optional[str] = None
    cfdi_app_path: Optional[str] = None
    cfdi_pac_app_path: Optional[str] = None

    # Digital Certificates (Flattened)
    fiel_cer: Optional[str] = None
    fiel_key: Optional[str] = None
    fiel_pass: Optional[str] = None
    fiel_access: Optional[str] = None
    fiel_cer_exp: Optional[int] = None
    fiel_key_exp: Optional[int] = None
    
    cfdi_cert_cer: Optional[str] = None
    cfdi_cert_key: Optional[str] = None
    cfdi_cert_pass: Optional[str] = None
    cfdi_cert_access: Optional[str] = None
    cfdi_cert_cer_exp: Optional[int] = None
    cfdi_cert_key_exp: Optional[int] = None
    
    cancel_cer: Optional[str] = None
    cancel_key: Optional[str] = None
    cancel_pass: Optional[str] = None
    cancel_access: Optional[str] = None
    cancel_cer_exp: Optional[int] = None
    cancel_key_exp: Optional[int] = None



    model_config = ConfigDict(from_attributes=True)
