"""
Carga de conjuntos FK para validación/mapeo de import CSV de partes.
Clarion: Clases, UOM, monedas, fracción Mex (+ histórico), países, sectores autorizados, excepción RFC.
"""
from typing import Set, Tuple, Optional
import logging

from core.database import CoreSessionLocal

logger = logging.getLogger(__name__)

# RFCs con excepción: E (UOM) obligatorio solo cuando D (Clase) está vacía; Preferencia solo cuando D no vacía
RFC_EXCEPTION_SET = {"CLA940831AZ5", "CTE980130518"}


def load_parts_fk_sets(
    tenant_id: int,
    company_id: int,
) -> Tuple[
    Set[str],
    Set[str],
    Set[str],
    Set[str],
    Set[str],
    Set[str],
    bool,
    bool,
]:
    """
    Carga conjuntos para validación CSV de partes (paridad Clarion).
    Devuelve:
    - valid_class_codes
    - valid_uom_codes
    - valid_currency_codes (claves moneda para G=MC y genéricas)
    - valid_fraction_mex_8 (fracción Mex 8 chars: TariffFraction + HistoricalTariffFraction)
    - valid_country_m3 (códigos país m3_key)
    - authorized_sector_keys (sectores con authorized=True)
    - company_has_prosec (Company.prosec)
    - is_rfc_exception (Company.rfc en RFC_EXCEPTION_SET)
    """
    valid_class_codes: Set[str] = set()
    valid_uom_codes: Set[str] = set()
    valid_currency_codes: Set[str] = set()
    valid_fraction_mex_8: Set[str] = set()
    valid_country_m3: Set[str] = set()
    authorized_sector_keys: Set[str] = set()
    company_has_prosec = False
    is_rfc_exception = False

    try:
        with CoreSessionLocal() as session:
            from api.v1.modules.a76.classes.models import Class
            from api.v1.modules.a76.general_catalogs.units_of_measure.models import UnitOfMeasure
            from api.v1.modules.public.reference_data.currency_types.models import CurrencyType
            from api.v1.modules.a76.general_catalogs.company.models import Company
            from api.v1.modules.public.reference_data.countries.models import Country
            from api.v1.modules.a76.general_catalogs.sectors.models import Sector
            from api.v1.modules.a76.general_catalogs.fractions.tariff_fractions.models import TariffFraction
            from api.v1.modules.a76.general_catalogs.fractions.historical_tariff_fractions.models import (
                HistoricalTariffFraction,
            )

            for c in (
                session.query(Class.class_code)
                .filter(
                    Class.tenant_id == tenant_id,
                    Class.company_id == company_id,
                )
                .all()
            ):
                if c[0]:
                    valid_class_codes.add((c[0] or "").strip().upper())

            for u in (
                session.query(UnitOfMeasure.code)
                .filter(
                    UnitOfMeasure.tenant_id == tenant_id,
                    UnitOfMeasure.company_id == company_id,
                )
                .all()
            ):
                if u[0]:
                    valid_uom_codes.add((u[0] or "").strip().upper())

            for cur in session.query(CurrencyType.code).all():
                if cur[0]:
                    valid_currency_codes.add((cur[0] or "").strip().upper())

            company = (
                session.query(Company)
                .filter(Company.id == company_id)
                .first()
            )
            if company:
                company_has_prosec = bool(company.prosec)
                rfc = (company.rfc or "").strip().upper()
                is_rfc_exception = rfc in RFC_EXCEPTION_SET

            for row in session.query(Country.m3_key).all():
                if row[0]:
                    valid_country_m3.add((row[0] or "").strip().upper())

            for row in (
                session.query(Sector.key)
                .filter(
                    Sector.authorized == True,
                    Sector.tenant_id == tenant_id,
                    Sector.company_id == company_id,
                )
                .all()
            ):
                if row[0]:
                    authorized_sector_keys.add((row[0] or "").strip().upper())

            for row in session.query(TariffFraction.code).all():
                if row[0]:
                    code = (row[0] or "").strip()
                    valid_fraction_mex_8.add(code[:8])

            for row in (
                session.query(HistoricalTariffFraction.historical_fraction)
                .filter(
                    HistoricalTariffFraction.tenant_id == tenant_id,
                    HistoricalTariffFraction.company_id == company_id,
                    HistoricalTariffFraction.historical_fraction.isnot(None),
                )
                .distinct()
                .all()
            ):
                if row[0] and (row[0] or "").strip():
                    valid_fraction_mex_8.add((row[0] or "").strip()[:8])

    except Exception as e:
        logger.warning("Parts import: could not load FK sets: %s", e)

    return (
        valid_class_codes,
        valid_uom_codes,
        valid_currency_codes,
        valid_fraction_mex_8,
        valid_country_m3,
        authorized_sector_keys,
        company_has_prosec,
        is_rfc_exception,
    )
