"""ISO country → currency mapping for freight routes and shipment pricing.

Currency is selected from the origin / pickup country.
"""

from __future__ import annotations

from core.countries import normalize_country_code

DEFAULT_CURRENCY = "USD"

# country_code -> ISO 4217 currency_code (or "N/A")
CURRENCY_CODE_BY_COUNTRY: dict[str, str] = {
    'AF': 'AFN',
    'AX': 'EUR',
    'AL': 'ALL',
    'DZ': 'DZD',
    'AS': 'USD',
    'AD': 'EUR',
    'AO': 'AOA',
    'AI': 'XCD',
    'AQ': 'N/A',
    'AG': 'XCD',
    'AR': 'ARS',
    'AM': 'AMD',
    'AW': 'AWG',
    'AU': 'AUD',
    'AT': 'EUR',
    'AZ': 'AZN',
    'BS': 'BSD',
    'BH': 'BHD',
    'BD': 'BDT',
    'BB': 'BBD',
    'BY': 'BYN',
    'BE': 'EUR',
    'BZ': 'BZD',
    'BJ': 'XOF',
    'BM': 'BMD',
    'BT': 'BTN',
    'BO': 'BOB',
    'BQ': 'USD',
    'BA': 'BAM',
    'BW': 'BWP',
    'BV': 'NOK',
    'BR': 'BRL',
    'IO': 'USD',
    'BN': 'BND',
    'BG': 'EUR',
    'BF': 'XOF',
    'BI': 'BIF',
    'CV': 'CVE',
    'KH': 'KHR',
    'CM': 'XAF',
    'CA': 'CAD',
    'KY': 'KYD',
    'CF': 'XAF',
    'TD': 'XAF',
    'CL': 'CLP',
    'CN': 'CNY',
    'CX': 'AUD',
    'CC': 'AUD',
    'CO': 'COP',
    'KM': 'KMF',
    'CG': 'XAF',
    'CD': 'CDF',
    'CK': 'NZD',
    'CR': 'CRC',
    'CI': 'XOF',
    'HR': 'EUR',
    'CU': 'CUP',
    'CW': 'ANG',
    'CY': 'EUR',
    'CZ': 'CZK',
    'DK': 'DKK',
    'DJ': 'DJF',
    'DM': 'XCD',
    'DO': 'DOP',
    'EC': 'USD',
    'EG': 'EGP',
    'SV': 'USD',
    'GQ': 'XAF',
    'ER': 'ERN',
    'EE': 'EUR',
    'SZ': 'SZL',
    'ET': 'ETB',
    'FK': 'FKP',
    'FO': 'DKK',
    'FJ': 'FJD',
    'FI': 'EUR',
    'FR': 'EUR',
    'GF': 'EUR',
    'PF': 'XPF',
    'TF': 'EUR',
    'GA': 'XAF',
    'GM': 'GMD',
    'GE': 'GEL',
    'DE': 'EUR',
    'GH': 'GHS',
    'GI': 'GIP',
    'GR': 'EUR',
    'GL': 'DKK',
    'GD': 'XCD',
    'GP': 'EUR',
    'GU': 'USD',
    'GT': 'GTQ',
    'GG': 'GBP',
    'GN': 'GNF',
    'GW': 'XOF',
    'GY': 'GYD',
    'HT': 'HTG',
    'HM': 'AUD',
    'VA': 'EUR',
    'HN': 'HNL',
    'HK': 'HKD',
    'HU': 'HUF',
    'IS': 'ISK',
    'IN': 'INR',
    'ID': 'IDR',
    'IR': 'IRR',
    'IQ': 'IQD',
    'IE': 'EUR',
    'IM': 'GBP',
    'IL': 'ILS',
    'IT': 'EUR',
    'JM': 'JMD',
    'JP': 'JPY',
    'JE': 'GBP',
    'JO': 'JOD',
    'KZ': 'KZT',
    'KE': 'KES',
    'KI': 'AUD',
    'KP': 'KPW',
    'KR': 'KRW',
    'KW': 'KWD',
    'KG': 'KGS',
    'LA': 'LAK',
    'LV': 'EUR',
    'LB': 'LBP',
    'LS': 'LSL',
    'LR': 'LRD',
    'LY': 'LYD',
    'LI': 'CHF',
    'LT': 'EUR',
    'LU': 'EUR',
    'MO': 'MOP',
    'MG': 'MGA',
    'MW': 'MWK',
    'MY': 'MYR',
    'MV': 'MVR',
    'ML': 'XOF',
    'MT': 'EUR',
    'MH': 'USD',
    'MQ': 'EUR',
    'MR': 'MRU',
    'MU': 'MUR',
    'YT': 'EUR',
    'MX': 'MXN',
    'FM': 'USD',
    'MD': 'MDL',
    'MC': 'EUR',
    'MN': 'MNT',
    'ME': 'EUR',
    'MS': 'XCD',
    'MA': 'MAD',
    'MZ': 'MZN',
    'MM': 'MMK',
    'NA': 'NAD',
    'NR': 'AUD',
    'NP': 'NPR',
    'NL': 'EUR',
    'NC': 'XPF',
    'NZ': 'NZD',
    'NI': 'NIO',
    'NE': 'XOF',
    'NG': 'NGN',
    'NU': 'NZD',
    'NF': 'AUD',
    'MK': 'MKD',
    'MP': 'USD',
    'NO': 'NOK',
    'OM': 'OMR',
    'PK': 'PKR',
    'PW': 'USD',
    'PS': 'ILS',
    'PA': 'PAB',
    'PG': 'PGK',
    'PY': 'PYG',
    'PE': 'PEN',
    'PH': 'PHP',
    'PN': 'NZD',
    'PL': 'PLN',
    'PT': 'EUR',
    'PR': 'USD',
    'QA': 'QAR',
    'RE': 'EUR',
    'RO': 'RON',
    'RU': 'RUB',
    'RW': 'RWF',
    'BL': 'EUR',
    'SH': 'SHP',
    'KN': 'XCD',
    'LC': 'XCD',
    'MF': 'EUR',
    'PM': 'EUR',
    'VC': 'XCD',
    'WS': 'WST',
    'SM': 'EUR',
    'ST': 'STN',
    'SA': 'SAR',
    'SN': 'XOF',
    'RS': 'RSD',
    'SC': 'SCR',
    'SL': 'SLE',
    'SG': 'SGD',
    'SX': 'ANG',
    'SK': 'EUR',
    'SI': 'EUR',
    'SB': 'SBD',
    'SO': 'SOS',
    'ZA': 'ZAR',
    'GS': 'GBP',
    'SS': 'SSP',
    'ES': 'EUR',
    'LK': 'LKR',
    'SD': 'SDG',
    'SR': 'SRD',
    'SJ': 'NOK',
    'SE': 'SEK',
    'CH': 'CHF',
    'SY': 'SYP',
    'TW': 'TWD',
    'TJ': 'TJS',
    'TZ': 'TZS',
    'TH': 'THB',
    'TL': 'USD',
    'TG': 'XOF',
    'TK': 'NZD',
    'TO': 'TOP',
    'TT': 'TTD',
    'TN': 'TND',
    'TR': 'TRY',
    'TM': 'TMT',
    'TC': 'USD',
    'TV': 'AUD',
    'UG': 'UGX',
    'UA': 'UAH',
    'AE': 'AED',
    'GB': 'GBP',
    'US': 'USD',
    'UM': 'USD',
    'UY': 'UYU',
    'UZ': 'UZS',
    'VU': 'VUV',
    'VE': 'VES',
    'VN': 'VND',
    'VG': 'USD',
    'VI': 'USD',
    'WF': 'XPF',
    'EH': 'MAD',
    'YE': 'YER',
    'ZM': 'ZMW',
    'ZW': 'ZWG',
}

# currency_code -> (name, symbol)
CURRENCY_META: dict[str, tuple[str, str]] = {
    'AED': ('UAE dirham', 'د.إ'),
    'AFN': ('Afghani', '؋'),
    'ALL': ('Lek', 'Lek'),
    'AMD': ('Armenian dram', '֏'),
    'ANG': ('Caribbean guilder', 'ƒ'),
    'AOA': ('Kwanza', 'Kz'),
    'ARS': ('Argentine peso', '$'),
    'AUD': ('Australian dollar', '$'),
    'AWG': ('Aruban florin', 'ƒ'),
    'AZN': ('Azerbaijani manat', '₼'),
    'BAM': ('Convertible mark', 'KM'),
    'BBD': ('Barbadian dollar', '$'),
    'BDT': ('Bangladeshi taka', '৳'),
    'BHD': ('Bahraini dinar', 'د.ب'),
    'BIF': ('Burundian franc', 'FBu'),
    'BMD': ('Bermudian dollar', '$'),
    'BND': ('Brunei dollar', '$'),
    'BOB': ('Boliviano', 'Bs.'),
    'BRL': ('Brazilian real', 'R$'),
    'BSD': ('Bahamian dollar', '$'),
    'BTN': ('Bhutanese ngultrum', 'Nu.'),
    'BWP': ('Pula', 'P'),
    'BYN': ('Belarusian ruble', 'Br'),
    'BZD': ('Belize dollar', '$'),
    'CAD': ('Canadian dollar', '$'),
    'CDF': ('Congolese franc', 'FC'),
    'CHF': ('Swiss franc', 'CHF'),
    'CLP': ('Chilean peso', '$'),
    'CNY': ('Chinese yuan', '¥'),
    'COP': ('Colombian peso', '$'),
    'CRC': ('Costa Rican colón', '₡'),
    'CUP': ('Cuban peso', '$'),
    'CVE': ('Cape Verdean escudo', '$'),
    'CZK': ('Czech koruna', 'Kč'),
    'DJF': ('Djiboutian franc', 'Fdj'),
    'DKK': ('Danish krone', 'kr'),
    'DOP': ('Dominican peso', '$'),
    'DZD': ('Algerian dinar', 'دج'),
    'EGP': ('Egyptian pound', '£'),
    'ERN': ('Eritrean nakfa', 'Nfk'),
    'ETB': ('Ethiopian birr', 'Br'),
    'EUR': ('Euro', '€'),
    'FJD': ('Fijian dollar', '$'),
    'FKP': ('Falkland Islands pound', '£'),
    'GBP': ('Pound sterling', '£'),
    'GEL': ('Georgian lari', '₾'),
    'GHS': ('Ghanaian cedi', '₵'),
    'GIP': ('Gibraltar pound', '£'),
    'GMD': ('Gambian dalasi', 'D'),
    'GNF': ('Guinean franc', 'FG'),
    'GTQ': ('Guatemalan quetzal', 'Q'),
    'GYD': ('Guyanese dollar', '$'),
    'HKD': ('Hong Kong dollar', '$'),
    'HNL': ('Honduran lempira', 'L'),
    'HTG': ('Haitian gourde', 'G'),
    'HUF': ('Hungarian forint', 'Ft'),
    'IDR': ('Indonesian rupiah', 'Rp'),
    'ILS': ('Israeli new shekel', '₪'),
    'INR': ('Indian rupee', '₹'),
    'IQD': ('Iraqi dinar', 'ع.د'),
    'IRR': ('Iranian rial', '﷼'),
    'ISK': ('Icelandic króna', 'kr'),
    'JMD': ('Jamaican dollar', '$'),
    'JOD': ('Jordanian dinar', 'د.ا'),
    'JPY': ('Japanese yen', '¥'),
    'KES': ('Kenyan shilling', 'KSh'),
    'KGS': ('Kyrgyzstani som', 'с'),
    'KHR': ('Cambodian riel', '៛'),
    'KMF': ('Comorian franc', 'CF'),
    'KPW': ('North Korean won', '₩'),
    'KRW': ('South Korean won', '₩'),
    'KWD': ('Kuwaiti dinar', 'د.ك'),
    'KYD': ('Cayman Islands dollar', '$'),
    'KZT': ('Kazakhstani tenge', '₸'),
    'LAK': ('Lao kip', '₭'),
    'LBP': ('Lebanese pound', 'ل.ل'),
    'LKR': ('Sri Lankan rupee', 'Rs'),
    'LRD': ('Liberian dollar', '$'),
    'LSL': ('Lesotho loti', 'L'),
    'LYD': ('Libyan dinar', 'ل.د'),
    'MAD': ('Moroccan dirham', 'د.م.'),
    'MDL': ('Moldovan leu', 'L'),
    'MGA': ('Malagasy ariary', 'Ar'),
    'MKD': ('Macedonian denar', 'ден'),
    'MMK': ('Myanmar kyat', 'K'),
    'MNT': ('Mongolian tögrög', '₮'),
    'MOP': ('Macanese pataca', 'MOP$'),
    'MRU': ('Mauritanian ouguiya', 'UM'),
    'MUR': ('Mauritian rupee', '₨'),
    'MVR': ('Maldivian rufiyaa', 'Rf'),
    'MWK': ('Malawian kwacha', 'MK'),
    'MXN': ('Mexican peso', '$'),
    'MYR': ('Malaysian ringgit', 'RM'),
    'MZN': ('Mozambican metical', 'MT'),
    'NAD': ('Namibian dollar', '$'),
    'NGN': ('Nigerian naira', '₦'),
    'NIO': ('Nicaraguan córdoba', 'C$'),
    'NOK': ('Norwegian krone', 'kr'),
    'NPR': ('Nepalese rupee', '₨'),
    'NZD': ('New Zealand dollar', '$'),
    'OMR': ('Omani rial', 'ر.ع.'),
    'PAB': ('Panamanian balboa', 'B/.'),
    'PEN': ('Peruvian sol', 'S/'),
    'PGK': ('Papua New Guinean kina', 'K'),
    'PHP': ('Philippine peso', '₱'),
    'PKR': ('Pakistani rupee', '₨'),
    'PLN': ('Polish złoty', 'zł'),
    'PYG': ('Paraguayan guaraní', '₲'),
    'QAR': ('Qatari riyal', 'ر.ق'),
    'RON': ('Romanian leu', 'lei'),
    'RSD': ('Serbian dinar', 'дин.'),
    'RUB': ('Russian ruble', '₽'),
    'RWF': ('Rwandan franc', 'FRw'),
    'SAR': ('Saudi riyal', '﷼'),
    'SBD': ('Solomon Islands dollar', '$'),
    'SCR': ('Seychellois rupee', '₨'),
    'SDG': ('Sudanese pound', 'ج.س.'),
    'SEK': ('Swedish krona', 'kr'),
    'SGD': ('Singapore dollar', '$'),
    'SHP': ('Saint Helena pound', '£'),
    'SLE': ('Sierra Leonean leone', 'Le'),
    'SOS': ('Somali shilling', 'Sh'),
    'SRD': ('Surinamese dollar', '$'),
    'SSP': ('South Sudanese pound', '£'),
    'STN': ('São Tomé and Príncipe dobra', 'Db'),
    'SYP': ('Syrian pound', '£'),
    'SZL': ('Swazi lilangeni', 'L'),
    'THB': ('Thai baht', '฿'),
    'TJS': ('Tajikistani somoni', 'ЅМ'),
    'TMT': ('Turkmenistan manat', 'm'),
    'TND': ('Tunisian dinar', 'د.ت'),
    'TOP': ('Tongan paʻanga', 'T$'),
    'TRY': ('Turkish lira', '₺'),
    'TTD': ('Trinidad and Tobago dollar', '$'),
    'TWD': ('New Taiwan dollar', 'NT$'),
    'TZS': ('Tanzanian shilling', 'Sh'),
    'UAH': ('Ukrainian hryvnia', '₴'),
    'UGX': ('Ugandan shilling', 'USh'),
    'USD': ('US dollar', '$'),
    'UYU': ('Uruguayan peso', '$U'),
    'UZS': ('Uzbekistani soʻm', 'сўм'),
    'VES': ('Venezuelan bolívar', 'Bs.'),
    'VND': ('Vietnamese đồng', '₫'),
    'VUV': ('Vanuatu vatu', 'VT'),
    'WST': ('Samoan tālā', 'T'),
    'XAF': ('Central African CFA franc', 'FCFA'),
    'XCD': ('East Caribbean dollar', '$'),
    'XOF': ('West African CFA franc', 'CFA'),
    'XPF': ('CFP franc', '₣'),
    'YER': ('Yemeni rial', '﷼'),
    'ZAR': ('South African rand', 'R'),
    'ZMW': ('Zambian kwacha', 'ZK'),
    'ZWG': ('Zimbabwe Gold', 'ZiG'),
}


def currency_code_for_country(country_code: str | None, *, default: str = DEFAULT_CURRENCY) -> str:
    """Return ISO currency for a country; falls back to default when missing/N/A."""
    code = normalize_country_code(country_code)
    if not code:
        return default
    currency = CURRENCY_CODE_BY_COUNTRY.get(code, default)
    if not currency or currency == 'N/A':
        return default
    return currency


def currency_for_shipment(shipment) -> str:
    """ISO 4217 from the shipment pickup country; stored currency is a fallback."""
    if shipment is None:
        return DEFAULT_CURRENCY
    pickup = getattr(shipment, 'pickup_country_code', None)
    if pickup:
        return currency_code_for_country(pickup)
    stored = (getattr(shipment, 'currency', None) or '').strip().upper()
    if stored:
        return stored
    return DEFAULT_CURRENCY


def currency_choices() -> list[tuple[str, str]]:
    """Unique currency codes for selects: (code, 'CODE — Name')."""
    items = []
    for code in sorted(CURRENCY_META.keys()):
        name, _symbol = CURRENCY_META[code]
        items.append((code, f'{code} — {name}'))
    if DEFAULT_CURRENCY not in CURRENCY_META:
        items.insert(0, (DEFAULT_CURRENCY, DEFAULT_CURRENCY))
    return items


def currency_map_for_frontend() -> dict[str, str]:
    """country_code -> currency_code for JS auto-select (skips N/A)."""
    return {
        code: cur
        for code, cur in CURRENCY_CODE_BY_COUNTRY.items()
        if cur and cur != 'N/A'
    }
