<?php
/**
 * Teleship Country Codes
 *
 * Static utility for normalizing country values to ISO 3166-1 alpha-2 codes.
 * Ported from Magento's OrderNormalizer country mapping.
 * Shared by both product sync and order sync.
 *
 * @package Teleship
 * @since 2.0.0
 */

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Class Teleship_Country_Codes
 */
class Teleship_Country_Codes {

    /**
     * Country name to ISO code mapping
     * All keys lowercase for case-insensitive matching
     *
     * @var array
     */
    private static $COUNTRY_NAME_TO_CODE = array(
        // A
        'afghanistan' => 'AF',
        'albania' => 'AL',
        'algeria' => 'DZ',
        'american samoa' => 'AS',
        'andorra' => 'AD',
        'angola' => 'AO',
        'anguilla' => 'AI',
        'antarctica' => 'AQ',
        'antigua and barbuda' => 'AG',
        'antigua' => 'AG',
        'argentina' => 'AR',
        'armenia' => 'AM',
        'aruba' => 'AW',
        'australia' => 'AU',
        'austria' => 'AT',
        'azerbaijan' => 'AZ',
        // B
        'bahamas' => 'BS',
        'the bahamas' => 'BS',
        'bahrain' => 'BH',
        'bangladesh' => 'BD',
        'barbados' => 'BB',
        'belarus' => 'BY',
        'belgium' => 'BE',
        'belize' => 'BZ',
        'benin' => 'BJ',
        'bermuda' => 'BM',
        'bhutan' => 'BT',
        'bolivia' => 'BO',
        'bosnia and herzegovina' => 'BA',
        'bosnia' => 'BA',
        'herzegovina' => 'BA',
        'botswana' => 'BW',
        'bouvet island' => 'BV',
        'brazil' => 'BR',
        'brasil' => 'BR',
        'british indian ocean territory' => 'IO',
        'brunei darussalam' => 'BN',
        'brunei' => 'BN',
        'bulgaria' => 'BG',
        'burkina faso' => 'BF',
        'burundi' => 'BI',
        'burma' => 'MM',
        // C
        'cambodia' => 'KH',
        'cameroon' => 'CM',
        'canada' => 'CA',
        'cape verde' => 'CV',
        'cabo verde' => 'CV',
        'cayman islands' => 'KY',
        'central african republic' => 'CF',
        'car' => 'CF',
        'chad' => 'TD',
        'chile' => 'CL',
        'china' => 'CN',
        'peoples republic of china' => 'CN',
        'prc' => 'CN',
        'pr china' => 'CN',
        'mainland china' => 'CN',
        'christmas island' => 'CX',
        'cocos islands' => 'CC',
        'cocos (keeling) islands' => 'CC',
        'keeling islands' => 'CC',
        'colombia' => 'CO',
        'comoros' => 'KM',
        'congo' => 'CG',
        'republic of the congo' => 'CG',
        'congo brazzaville' => 'CG',
        'congo, democratic republic' => 'CD',
        'democratic republic of the congo' => 'CD',
        'congo kinshasa' => 'CD',
        'drc' => 'CD',
        'dr congo' => 'CD',
        'zaire' => 'CD',
        'cook islands' => 'CK',
        'costa rica' => 'CR',
        'ivory coast' => 'CI',
        'croatia' => 'HR',
        'cuba' => 'CU',
        'curacao' => 'CW',
        'cyprus' => 'CY',
        'czech republic' => 'CZ',
        'czechia' => 'CZ',
        // D
        'denmark' => 'DK',
        'djibouti' => 'DJ',
        'dominica' => 'DM',
        'dominican republic' => 'DO',
        // E
        'ecuador' => 'EC',
        'egypt' => 'EG',
        'el salvador' => 'SV',
        'equatorial guinea' => 'GQ',
        'eritrea' => 'ER',
        'estonia' => 'EE',
        'eswatini' => 'SZ',
        'swaziland' => 'SZ',
        'ethiopia' => 'ET',
        // F
        'falkland islands' => 'FK',
        'falklands' => 'FK',
        'faroe islands' => 'FO',
        'fiji' => 'FJ',
        'finland' => 'FI',
        'france' => 'FR',
        'french guiana' => 'GF',
        'french polynesia' => 'PF',
        'french southern territories' => 'TF',
        // G
        'gabon' => 'GA',
        'gambia' => 'GM',
        'the gambia' => 'GM',
        'georgia' => 'GE',
        'germany' => 'DE',
        'deutschland' => 'DE',
        'ghana' => 'GH',
        'gibraltar' => 'GI',
        'greece' => 'GR',
        'greenland' => 'GL',
        'grenada' => 'GD',
        'guadeloupe' => 'GP',
        'guam' => 'GU',
        'guatemala' => 'GT',
        'guernsey' => 'GG',
        'guinea' => 'GN',
        'guinea-bissau' => 'GW',
        'guinea bissau' => 'GW',
        'guyana' => 'GY',
        // H
        'haiti' => 'HT',
        'heard island and mcdonald islands' => 'HM',
        'heard and mcdonald islands' => 'HM',
        'holy see' => 'VA',
        'vatican city' => 'VA',
        'vatican' => 'VA',
        'honduras' => 'HN',
        'hong kong' => 'HK',
        'hong kong sar' => 'HK',
        'hk' => 'HK',
        'hungary' => 'HU',
        // I
        'iceland' => 'IS',
        'india' => 'IN',
        'indonesia' => 'ID',
        'iran' => 'IR',
        'islamic republic of iran' => 'IR',
        'iraq' => 'IQ',
        'ireland' => 'IE',
        'republic of ireland' => 'IE',
        'eire' => 'IE',
        'isle of man' => 'IM',
        'israel' => 'IL',
        'italy' => 'IT',
        'italia' => 'IT',
        // J
        'jamaica' => 'JM',
        'japan' => 'JP',
        'jersey' => 'JE',
        'jordan' => 'JO',
        // K
        'kazakhstan' => 'KZ',
        'kenya' => 'KE',
        'kiribati' => 'KI',
        'korea, north' => 'KP',
        'north korea' => 'KP',
        'dprk' => 'KP',
        'korea, south' => 'KR',
        'south korea' => 'KR',
        'korea' => 'KR',
        'republic of korea' => 'KR',
        'rok' => 'KR',
        'kuwait' => 'KW',
        'kyrgyzstan' => 'KG',
        // L
        'laos' => 'LA',
        'latvia' => 'LV',
        'lebanon' => 'LB',
        'lesotho' => 'LS',
        'liberia' => 'LR',
        'libya' => 'LY',
        'liechtenstein' => 'LI',
        'lithuania' => 'LT',
        'luxembourg' => 'LU',
        // M
        'macau' => 'MO',
        'macao' => 'MO',
        'macau sar' => 'MO',
        'madagascar' => 'MG',
        'malawi' => 'MW',
        'malaysia' => 'MY',
        'maldives' => 'MV',
        'mali' => 'ML',
        'malta' => 'MT',
        'marshall islands' => 'MH',
        'martinique' => 'MQ',
        'mauritania' => 'MR',
        'mauritius' => 'MU',
        'mayotte' => 'YT',
        'mexico' => 'MX',
        'micronesia' => 'FM',
        'federated states of micronesia' => 'FM',
        'moldova' => 'MD',
        'republic of moldova' => 'MD',
        'monaco' => 'MC',
        'mongolia' => 'MN',
        'montenegro' => 'ME',
        'montserrat' => 'MS',
        'morocco' => 'MA',
        'mozambique' => 'MZ',
        'myanmar' => 'MM',
        'north macedonia' => 'MK',
        'macedonia' => 'MK',
        'republic of north macedonia' => 'MK',
        // N
        'namibia' => 'NA',
        'nauru' => 'NR',
        'nepal' => 'NP',
        'netherlands' => 'NL',
        'the netherlands' => 'NL',
        'holland' => 'NL',
        'new caledonia' => 'NC',
        'new zealand' => 'NZ',
        'nz' => 'NZ',
        'nicaragua' => 'NI',
        'niger' => 'NE',
        'nigeria' => 'NG',
        'niue' => 'NU',
        'norfolk island' => 'NF',
        'northern mariana islands' => 'MP',
        'norway' => 'NO',
        // O
        'oman' => 'OM',
        // P
        'pakistan' => 'PK',
        'palau' => 'PW',
        'palestine' => 'PS',
        'palestinian territory' => 'PS',
        'panama' => 'PA',
        'papua new guinea' => 'PG',
        'png' => 'PG',
        'paraguay' => 'PY',
        'peru' => 'PE',
        'philippines' => 'PH',
        'the philippines' => 'PH',
        'pitcairn' => 'PN',
        'pitcairn islands' => 'PN',
        'poland' => 'PL',
        'polska' => 'PL',
        'portugal' => 'PT',
        'puerto rico' => 'PR',
        // Q
        'qatar' => 'QA',
        // R
        'reunion' => 'RE',
        'romania' => 'RO',
        'russia' => 'RU',
        'russian federation' => 'RU',
        'rwanda' => 'RW',
        // S
        'saint barthelemy' => 'BL',
        'saint helena' => 'SH',
        'st helena' => 'SH',
        'saint kitts and nevis' => 'KN',
        'st kitts and nevis' => 'KN',
        'st kitts' => 'KN',
        'saint lucia' => 'LC',
        'st lucia' => 'LC',
        'saint martin' => 'MF',
        'saint pierre and miquelon' => 'PM',
        'st pierre and miquelon' => 'PM',
        'st pierre' => 'PM',
        'saint vincent and the grenadines' => 'VC',
        'st vincent and the grenadines' => 'VC',
        'st vincent' => 'VC',
        'grenadines' => 'VC',
        'samoa' => 'WS',
        'san marino' => 'SM',
        'sao tome and principe' => 'ST',
        'saudi arabia' => 'SA',
        'ksa' => 'SA',
        'senegal' => 'SN',
        'serbia' => 'RS',
        'seychelles' => 'SC',
        'sierra leone' => 'SL',
        'singapore' => 'SG',
        'sint maarten' => 'SX',
        'slovakia' => 'SK',
        'slovak republic' => 'SK',
        'slovenia' => 'SI',
        'solomon islands' => 'SB',
        'somalia' => 'SO',
        'south africa' => 'ZA',
        'rsa' => 'ZA',
        'south georgia and the south sandwich islands' => 'GS',
        'south georgia' => 'GS',
        'south sandwich islands' => 'GS',
        'south sudan' => 'SS',
        'spain' => 'ES',
        'sri lanka' => 'LK',
        'ceylon' => 'LK',
        'sudan' => 'SD',
        'suriname' => 'SR',
        'svalbard and jan mayen' => 'SJ',
        'sweden' => 'SE',
        'switzerland' => 'CH',
        'syria' => 'SY',
        'syrian arab republic' => 'SY',
        // T
        'taiwan' => 'TW',
        'taiwan, province of china' => 'TW',
        'republic of china' => 'TW',
        'roc' => 'TW',
        'chinese taipei' => 'TW',
        'tajikistan' => 'TJ',
        'tanzania' => 'TZ',
        'united republic of tanzania' => 'TZ',
        'thailand' => 'TH',
        'timor-leste' => 'TL',
        'timor leste' => 'TL',
        'east timor' => 'TL',
        'togo' => 'TG',
        'tokelau' => 'TK',
        'tonga' => 'TO',
        'trinidad and tobago' => 'TT',
        'trinidad' => 'TT',
        'tobago' => 'TT',
        'tunisia' => 'TN',
        'turkey' => 'TR',
        'turkiye' => 'TR',
        'turkmenistan' => 'TM',
        'turks and caicos islands' => 'TC',
        'turks and caicos' => 'TC',
        'tuvalu' => 'TV',
        // U
        'uganda' => 'UG',
        'ukraine' => 'UA',
        'united arab emirates' => 'AE',
        'uae' => 'AE',
        'emirates' => 'AE',
        'united kingdom' => 'GB',
        'uk' => 'GB',
        'great britain' => 'GB',
        'britain' => 'GB',
        'england' => 'GB',
        'scotland' => 'GB',
        'wales' => 'GB',
        'northern ireland' => 'GB',
        'united states' => 'US',
        'united states of america' => 'US',
        'usa' => 'US',
        'us' => 'US',
        'america' => 'US',
        'united states minor outlying islands' => 'UM',
        'uruguay' => 'UY',
        'uzbekistan' => 'UZ',
        // V
        'vanuatu' => 'VU',
        'venezuela' => 'VE',
        'vietnam' => 'VN',
        'viet nam' => 'VN',
        'virgin islands, british' => 'VG',
        'british virgin islands' => 'VG',
        'bvi' => 'VG',
        'virgin islands, u.s.' => 'VI',
        'us virgin islands' => 'VI',
        'usvi' => 'VI',
        // W
        'wallis and futuna' => 'WF',
        'wallis and futuna islands' => 'WF',
        'western sahara' => 'EH',
        // Y
        'yemen' => 'YE',
        // Z
        'zambia' => 'ZM',
        'zimbabwe' => 'ZW',
    );

    /**
     * Normalize a country value to ISO 3166-1 alpha-2 code
     *
     * Accepts ISO codes or full country names.
     *
     * @param string $value Country code or name.
     * @return string|null ISO code or null if not recognized.
     */
    public static function normalize($value) {
        if (empty($value) || !is_string($value)) {
            return null;
        }

        $value = trim($value);

        // Already a valid 2-letter ISO code
        if (preg_match('/^[A-Z]{2}$/i', $value)) {
            return strtoupper($value);
        }

        // Try country name lookup
        return self::name_to_code($value);
    }

    /**
     * Convert country name to ISO code (case-insensitive)
     *
     * @param string $name Country name.
     * @return string|null ISO code or null if not found.
     */
    public static function name_to_code($name) {
        if (empty($name) || !is_string($name)) {
            return null;
        }

        $normalized = strtolower(trim($name));
        return isset(self::$COUNTRY_NAME_TO_CODE[$normalized]) ? self::$COUNTRY_NAME_TO_CODE[$normalized] : null;
    }
}
