use serde::{Deserialize, Serialize};
use std::fmt;
use std::fmt::Formatter;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
pub enum Country {
    AD,
    AE,
    AF,
    AG,
    AI,
    AL,
    AM,
    AO,
    AQ,
    AR,
    AS,
    AT,
    AU,
    AW,
    AX,
    AZ,
    BA,
    BB,
    BD,
    BE,
    BF,
    BG,
    BH,
    BI,
    BJ,
    BL,
    BM,
    BN,
    BO,
    BQ,
    BR,
    BS,
    BT,
    BV,
    BW,
    BY,
    BZ,
    CA,
    CC,
    CD,
    CF,
    CG,
    CH,
    CI,
    CK,
    CL,
    CM,
    CN,
    CO,
    CR,
    CU,
    CV,
    CW,
    CX,
    CY,
    CZ,
    DE,
    DJ,
    DK,
    DM,
    DO,
    DZ,
    EC,
    EE,
    EG,
    EH,
    ER,
    ES,
    ET,
    FI,
    FJ,
    FK,
    FM,
    FO,
    FR,
    GA,
    GB,
    GD,
    GE,
    GF,
    GG,
    GH,
    GI,
    GL,
    GM,
    GN,
    GP,
    GQ,
    GR,
    GS,
    GT,
    GU,
    GW,
    GY,
    HK,
    HM,
    HN,
    HR,
    HT,
    HU,
    ID,
    IE,
    IL,
    IM,
    IN,
    IO,
    IQ,
    IR,
    IS,
    IT,
    JE,
    JM,
    JO,
    JP,
    KE,
    KG,
    KH,
    KI,
    KM,
    KN,
    KP,
    KR,
    KW,
    KY,
    KZ,
    LA,
    LB,
    LC,
    LI,
    LK,
    LR,
    LS,
    LT,
    LU,
    LV,
    LY,
    MA,
    MC,
    MD,
    ME,
    MF,
    MG,
    MH,
    MK,
    ML,
    MM,
    MN,
    MO,
    MP,
    MQ,
    MR,
    MS,
    MT,
    MU,
    MV,
    MW,
    MX,
    MY,
    MZ,
    NA,
    NC,
    NE,
    NF,
    NG,
    NI,
    NL,
    NO,
    NP,
    NR,
    NU,
    NZ,
    OM,
    PA,
    PE,
    PF,
    PG,
    PH,
    PK,
    PL,
    PM,
    PN,
    PR,
    PS,
    PT,
    PW,
    PY,
    QA,
    RE,
    RO,
    RS,
    RU,
    RW,
    SA,
    SB,
    SC,
    SD,
    SE,
    SG,
    SH,
    SI,
    SJ,
    SK,
    SL,
    SM,
    SN,
    SO,
    SR,
    SS,
    ST,
    SV,
    SX,
    SY,
    SZ,
    TC,
    TD,
    TF,
    TG,
    TH,
    TJ,
    TK,
    TL,
    TM,
    TN,
    TO,
    TR,
    TT,
    TV,
    TW,
    TZ,
    UA,
    UG,
    UM,
    US,
    UY,
    UZ,
    VA,
    VC,
    VE,
    VG,
    VI,
    VN,
    VU,
    WF,
    WS,
    YE,
    YT,
    ZA,
    ZM,
    ZW,
    #[default]
    ZZ,
}

impl fmt::Display for Country {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        if self.eq(&Country::ZZ) {
            write!(f, "?")
        } else {
            write!(f, "{self:?}")
        }
    }
}

impl Country {
    pub fn from_str(code: &str) -> Self {
        #![allow(clippy::too_many_lines)]
        match code {
            "AD" => Country::AD,
            "AE" => Country::AE,
            "AF" => Country::AF,
            "AG" => Country::AG,
            "AI" => Country::AI,
            "AL" => Country::AL,
            "AM" => Country::AM,
            "AO" => Country::AO,
            "AQ" => Country::AQ,
            "AR" => Country::AR,
            "AS" => Country::AS,
            "AT" => Country::AT,
            "AU" => Country::AU,
            "AW" => Country::AW,
            "AX" => Country::AX,
            "AZ" => Country::AZ,
            "BA" => Country::BA,
            "BB" => Country::BB,
            "BD" => Country::BD,
            "BE" => Country::BE,
            "BF" => Country::BF,
            "BG" => Country::BG,
            "BH" => Country::BH,
            "BI" => Country::BI,
            "BJ" => Country::BJ,
            "BL" => Country::BL,
            "BM" => Country::BM,
            "BN" => Country::BN,
            "BO" => Country::BO,
            "BQ" => Country::BQ,
            "BR" => Country::BR,
            "BS" => Country::BS,
            "BT" => Country::BT,
            "BV" => Country::BV,
            "BW" => Country::BW,
            "BY" => Country::BY,
            "BZ" => Country::BZ,
            "CA" => Country::CA,
            "CC" => Country::CC,
            "CD" => Country::CD,
            "CF" => Country::CF,
            "CG" => Country::CG,
            "CH" => Country::CH,
            "CI" => Country::CI,
            "CK" => Country::CK,
            "CL" => Country::CL,
            "CM" => Country::CM,
            "CN" => Country::CN,
            "CO" => Country::CO,
            "CR" => Country::CR,
            "CU" => Country::CU,
            "CV" => Country::CV,
            "CW" => Country::CW,
            "CX" => Country::CX,
            "CY" => Country::CY,
            "CZ" => Country::CZ,
            "DE" => Country::DE,
            "DJ" => Country::DJ,
            "DK" => Country::DK,
            "DM" => Country::DM,
            "DO" => Country::DO,
            "DZ" => Country::DZ,
            "EC" => Country::EC,
            "EE" => Country::EE,
            "EG" => Country::EG,
            "EH" => Country::EH,
            "ER" => Country::ER,
            "ES" => Country::ES,
            "ET" => Country::ET,
            "FI" => Country::FI,
            "FJ" => Country::FJ,
            "FK" => Country::FK,
            "FM" => Country::FM,
            "FO" => Country::FO,
            "FR" => Country::FR,
            "GA" => Country::GA,
            "GB" => Country::GB,
            "GD" => Country::GD,
            "GE" => Country::GE,
            "GF" => Country::GF,
            "GG" => Country::GG,
            "GH" => Country::GH,
            "GI" => Country::GI,
            "GL" => Country::GL,
            "GM" => Country::GM,
            "GN" => Country::GN,
            "GP" => Country::GP,
            "GQ" => Country::GQ,
            "GR" => Country::GR,
            "GS" => Country::GS,
            "GT" => Country::GT,
            "GU" => Country::GU,
            "GW" => Country::GW,
            "GY" => Country::GY,
            "HK" => Country::HK,
            "HM" => Country::HM,
            "HN" => Country::HN,
            "HR" => Country::HR,
            "HT" => Country::HT,
            "HU" => Country::HU,
            "ID" => Country::ID,
            "IE" => Country::IE,
            "IL" => Country::IL,
            "IM" => Country::IM,
            "IN" => Country::IN,
            "IO" => Country::IO,
            "IQ" => Country::IQ,
            "IR" => Country::IR,
            "IS" => Country::IS,
            "IT" => Country::IT,
            "JE" => Country::JE,
            "JM" => Country::JM,
            "JO" => Country::JO,
            "JP" => Country::JP,
            "KE" => Country::KE,
            "KG" => Country::KG,
            "KH" => Country::KH,
            "KI" => Country::KI,
            "KM" => Country::KM,
            "KN" => Country::KN,
            "KP" => Country::KP,
            "KR" => Country::KR,
            "KW" => Country::KW,
            "KY" => Country::KY,
            "KZ" => Country::KZ,
            "LA" => Country::LA,
            "LB" => Country::LB,
            "LC" => Country::LC,
            "LI" => Country::LI,
            "LK" => Country::LK,
            "LR" => Country::LR,
            "LS" => Country::LS,
            "LT" => Country::LT,
            "LU" => Country::LU,
            "LV" => Country::LV,
            "LY" => Country::LY,
            "MA" => Country::MA,
            "MC" => Country::MC,
            "MD" => Country::MD,
            "ME" => Country::ME,
            "MF" => Country::MF,
            "MG" => Country::MG,
            "MH" => Country::MH,
            "MK" => Country::MK,
            "ML" => Country::ML,
            "MM" => Country::MM,
            "MN" => Country::MN,
            "MO" => Country::MO,
            "MP" => Country::MP,
            "MQ" => Country::MQ,
            "MR" => Country::MR,
            "MS" => Country::MS,
            "MT" => Country::MT,
            "MU" => Country::MU,
            "MV" => Country::MV,
            "MW" => Country::MW,
            "MX" => Country::MX,
            "MY" => Country::MY,
            "MZ" => Country::MZ,
            "NA" => Country::NA,
            "NC" => Country::NC,
            "NE" => Country::NE,
            "NF" => Country::NF,
            "NG" => Country::NG,
            "NI" => Country::NI,
            "NL" => Country::NL,
            "NO" => Country::NO,
            "NP" => Country::NP,
            "NR" => Country::NR,
            "NU" => Country::NU,
            "NZ" => Country::NZ,
            "OM" => Country::OM,
            "PA" => Country::PA,
            "PE" => Country::PE,
            "PF" => Country::PF,
            "PG" => Country::PG,
            "PH" => Country::PH,
            "PK" => Country::PK,
            "PL" => Country::PL,
            "PM" => Country::PM,
            "PN" => Country::PN,
            "PR" => Country::PR,
            "PS" => Country::PS,
            "PT" => Country::PT,
            "PW" => Country::PW,
            "PY" => Country::PY,
            "QA" => Country::QA,
            "RE" => Country::RE,
            "RO" => Country::RO,
            "RS" => Country::RS,
            "RU" => Country::RU,
            "RW" => Country::RW,
            "SA" => Country::SA,
            "SB" => Country::SB,
            "SC" => Country::SC,
            "SD" => Country::SD,
            "SE" => Country::SE,
            "SG" => Country::SG,
            "SH" => Country::SH,
            "SI" => Country::SI,
            "SJ" => Country::SJ,
            "SK" => Country::SK,
            "SL" => Country::SL,
            "SM" => Country::SM,
            "SN" => Country::SN,
            "SO" => Country::SO,
            "SR" => Country::SR,
            "SS" => Country::SS,
            "ST" => Country::ST,
            "SV" => Country::SV,
            "SX" => Country::SX,
            "SY" => Country::SY,
            "SZ" => Country::SZ,
            "TC" => Country::TC,
            "TD" => Country::TD,
            "TF" => Country::TF,
            "TG" => Country::TG,
            "TH" => Country::TH,
            "TJ" => Country::TJ,
            "TK" => Country::TK,
            "TL" => Country::TL,
            "TM" => Country::TM,
            "TN" => Country::TN,
            "TO" => Country::TO,
            "TR" => Country::TR,
            "TT" => Country::TT,
            "TV" => Country::TV,
            "TW" => Country::TW,
            "TZ" => Country::TZ,
            "UA" => Country::UA,
            "UG" => Country::UG,
            "UM" => Country::UM,
            "US" => Country::US,
            "UY" => Country::UY,
            "UZ" => Country::UZ,
            "VA" => Country::VA,
            "VC" => Country::VC,
            "VE" => Country::VE,
            "VG" => Country::VG,
            "VI" => Country::VI,
            "VN" => Country::VN,
            "VU" => Country::VU,
            "WF" => Country::WF,
            "WS" => Country::WS,
            "YE" => Country::YE,
            "YT" => Country::YT,
            "ZA" => Country::ZA,
            "ZM" => Country::ZM,
            "ZW" => Country::ZW,
            _ => Country::ZZ,
        }
    }
}
