"""Load type flags: country_to_country vs local (mutually exclusive)."""

from rest_framework import serializers

LOAD_TYPE_LOCAL = 'local'
LOAD_TYPE_COUNTRY_TO_COUNTRY = 'country_to_country'
LOAD_TYPE_CHOICES = frozenset({LOAD_TYPE_LOCAL, LOAD_TYPE_COUNTRY_TO_COUNTRY})


def validate_load_type_xor(country_to_country: bool, local: bool) -> None:
    if country_to_country == local:
        raise serializers.ValidationError(
            'Exactly one of country_to_country or local must be true (the other must be false).'
        )


def transporter_can_access_shipment(profile, shipment) -> bool:
    if profile.country_to_country:
        return True
    return bool(profile.local and shipment.local)


def parse_load_type_query(raw) -> str | None:
    """
    Parse optional load_type query param.
    Returns None when omitted; 'local' or 'country_to_country' when valid.
    Raises ValueError for invalid values.
    """
    if raw in (None, ''):
        return None
    value = str(raw).strip().lower().replace('-', '_')
    if value not in LOAD_TYPE_CHOICES:
        raise ValueError('load_type must be local or country_to_country.')
    return value


def shipment_matches_load_type_filter(shipment, load_type: str | None) -> bool:
    """
    Strict filter:
    - local → only shipment.local (excludes all C2C)
    - country_to_country → only true cross-border C2C (excludes local and same-country)
    - None → no extra filter
    """
    if not load_type:
        return True
    if load_type == LOAD_TYPE_LOCAL:
        return bool(shipment.local) and not bool(shipment.country_to_country)
    if load_type == LOAD_TYPE_COUNTRY_TO_COUNTRY:
        if not shipment.country_to_country or shipment.local:
            return False
        from core.countries import normalize_country_code

        pickup = normalize_country_code(shipment.pickup_country_code)
        delivery = normalize_country_code(shipment.delivery_country_code)
        # Same-country routes are not country-to-country loads for this filter.
        return bool(pickup and delivery and pickup != delivery)
    return False
