use std::fmt;
use strum_macros::{EnumIter, EnumString};
use serde_derive::{Deserialize, Serialize};

/// Enum containing every SEPA-specified transaction type identification code.
///
/// See here for source:
/// http://www.sepaforcorporates.com/swift-for-corporates/list-mt940-transaction-type-identification-codes/
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, EnumString, EnumIter)]
pub enum TransactionTypeIdentificationCode {
    BNK,
    BOE,
    BRF,
    CAR,
    CAS,
    CHG,
    CHK,
    CLR,
    CMI,
    CMN,
    CMP,
    CMS,
    CMT,
    CMZ,
    COL,
    COM,
    CPN,
    DCR,
    DDT,
    DIS,
    DIV,
    EQA,
    EXT,
    FEX,
    INT,
    LBX,
    LDP,
    MAR,
    MAT,
    MGT,
    MSC,
    NWI,
    ODC,
    OPT,
    PCH,
    POP,
    PRN,
    REC,
    RED,
    RIG,
    RTI,
    SAL,
    SEC,
    SLE,
    STO,
    STP,
    SUB,
    SWP,
    TAX,
    TCK,
    TCM,
    TRA,
    TRF,
    TRN,
    UWC,
    VDA,
    WAR,
    NonStandard(String),
}

impl fmt::Display for TransactionTypeIdentificationCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let description = match self {
            TransactionTypeIdentificationCode::BNK => "Securities Related Item – Bank fees",
            TransactionTypeIdentificationCode::BOE => "Bill of exchange",
            TransactionTypeIdentificationCode::BRF => "Brokerage fee",
            TransactionTypeIdentificationCode::CAR => "Securities Related Item – Corporate Actions Related (Should only be used when no specific corporate action event code is available)",
            TransactionTypeIdentificationCode::CAS => "Securities Related Item – Cash in Lieu",
            TransactionTypeIdentificationCode::CHG => "Charges and other expenses",
            TransactionTypeIdentificationCode::CHK => "Cheques",
            TransactionTypeIdentificationCode::CLR => "Cash letters/Cheques remittance",
            TransactionTypeIdentificationCode::CMI => "Cash management item – No detail",
            TransactionTypeIdentificationCode::CMN => "Cash management item – Notional pooling",
            TransactionTypeIdentificationCode::CMP => "Compensation claims",
            TransactionTypeIdentificationCode::CMS => "Cash management item – Sweeping",
            TransactionTypeIdentificationCode::CMT => "Cash management item -Topping",
            TransactionTypeIdentificationCode::CMZ => "Cash management item – Zero balancing",
            TransactionTypeIdentificationCode::COL => "Collections (used when entering a principal amount)",
            TransactionTypeIdentificationCode::COM => "Commission",
            TransactionTypeIdentificationCode::CPN => "Securities Related Item – Coupon payments",
            TransactionTypeIdentificationCode::DCR => "Documentary credit (used when entering a principal amount)",
            TransactionTypeIdentificationCode::DDT => "Direct Debit Item",
            TransactionTypeIdentificationCode::DIS => "Securities Related Item – Gains disbursement",
            TransactionTypeIdentificationCode::DIV => "Securities Related Item – Dividends",
            TransactionTypeIdentificationCode::EQA => "Equivalent amount",
            TransactionTypeIdentificationCode::EXT => "Securities Related Item – External transfer for own account",
            TransactionTypeIdentificationCode::FEX => "Foreign exchange",
            TransactionTypeIdentificationCode::INT => "Interest",
            TransactionTypeIdentificationCode::LBX => "Lock box",
            TransactionTypeIdentificationCode::LDP => "Loan deposit",
            TransactionTypeIdentificationCode::MAR => "Securities Related Item – Margin payments/Receipts",
            TransactionTypeIdentificationCode::MAT => "Securities Related Item – Maturity",
            TransactionTypeIdentificationCode::MGT => "Securities Related Item – Management fees",
            TransactionTypeIdentificationCode::MSC => "Miscellaneous",
            TransactionTypeIdentificationCode::NWI => "Securities Related Item – New issues distribution",
            TransactionTypeIdentificationCode::ODC => "Overdraft charge",
            TransactionTypeIdentificationCode::OPT => "Securities Related Item – Options",
            TransactionTypeIdentificationCode::PCH => "Securities Related Item – Purchase (including STIF and Time deposits)",
            TransactionTypeIdentificationCode::POP => "Securities Related Item – Pair-off proceeds",
            TransactionTypeIdentificationCode::PRN => "Securities Related Item – Principal pay-down/pay-up",
            TransactionTypeIdentificationCode::REC => "Securities Related Item – Tax reclaim",
            TransactionTypeIdentificationCode::RED => "Securities Related Item – Redemption/Withdrawal",
            TransactionTypeIdentificationCode::RIG => "Securities Related Item – Rights",
            TransactionTypeIdentificationCode::RTI => "Returned item",
            TransactionTypeIdentificationCode::SAL => "Securities Related Item – Sale (including STIF and Time deposits)",
            TransactionTypeIdentificationCode::SEC => "Securities (used when entering a principal amount)",
            TransactionTypeIdentificationCode::SLE => "Securities Related Item – Securities lending related",
            TransactionTypeIdentificationCode::STO => "Standing order",
            TransactionTypeIdentificationCode::STP => "Securities Related Item – Stamp duty",
            TransactionTypeIdentificationCode::SUB => "Securities Related Item – Subscription",
            TransactionTypeIdentificationCode::SWP => "Securities Related Item – SWAP payment",
            TransactionTypeIdentificationCode::TAX => "Securities Related Item – Withholding tax payment",
            TransactionTypeIdentificationCode::TCK => "Travellers cheques",
            TransactionTypeIdentificationCode::TCM => "Securities Related Item – Tripartite collateral management",
            TransactionTypeIdentificationCode::TRA => "Securities Related Item – Internal transfer for own account",
            TransactionTypeIdentificationCode::TRF => "Transfer",
            TransactionTypeIdentificationCode::TRN => "Securities Related Item – Transaction fee",
            TransactionTypeIdentificationCode::UWC => "Securities Related Item – Underwriting commission",
            TransactionTypeIdentificationCode::VDA => "Value date adjustment (used with an entry made to withdraw an incorrectly dated entry – it will be followed by the correct entry with the relevant code)",
            TransactionTypeIdentificationCode::WAR => "Securities Related Item – Warrant",
            TransactionTypeIdentificationCode::NonStandard(_) => "Non-standard MT940 Transaction Type Identification Code",
        };
        write!(f, "({:?}, {})", self, description)
    }
}
