use crate::parser::XmlReader;
use crate::XmlResult;
use quick_xml::events::BytesStart;

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[doc = "Specifies the bank transaction code domain, as published in an external bank transaction code domain code list.\r\nExternal code sets can be downloaded from www.iso20022.org."]
pub enum ExternalBankTransactionDomain1Code {
    AccountManagement,
    CashManagement,
    Commodities,
    Derivatives,
    ExtendedDomain,
    ForeignExchange,
    LoansDepositsSyndications,
    Payments,
    PreciousMetal,
    Securities,
    TradeServices,
}

impl<'a> ExternalBankTransactionDomain1Code {
    pub(crate) fn parse(reader: &mut XmlReader<'a>, _start: &BytesStart<'_>) -> XmlResult<Self> {
        let value = match &*reader.expect_text()? {
            "ACMT" => Self::AccountManagement,
            "CAMT" => Self::CashManagement,
            "CMDT" => Self::Commodities,
            "DERV" => Self::Derivatives,
            "XTND" => Self::ExtendedDomain,
            "FORX" => Self::ForeignExchange,
            "LDAS" => Self::LoansDepositsSyndications,
            "PMNT" => Self::Payments,
            "PMET" => Self::PreciousMetal,
            "SECU" => Self::Securities,
            "TRAD" => Self::TradeServices,

            tag => todo!("handle tag {tag:?}"),
        };
        Ok(value)
    }
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[doc = "Specifies the bank transaction code family, as published in an external bank transaction code family code list.\r\nExternal code sets can be downloaded from www.iso20022.org."]
pub enum ExternalBankTransactionFamily1Code {
    // Cash Management
    AccountBalancing,
    CashPooling,

    // Derivatives
    ListedDerivativesFutures,
    ListedDerivativesOptions,
    OtcDerivativesBonds,
    OtcDerivativesCreditDerivatives,
    OtcDerivativesEquity,
    OtcDerivativesInterestRates,
    OtcDerivativesStructuredExoticDerivatives,
    OtcDerivativesSwaps,

    // Foreign Exchange
    Forwards,
    Futures,
    NonDeliverable,
    Spots,
    Swaps,

    // Generic
    MiscellaneousCreditOperations,
    MiscellaneousDebitOperations,
    NotAvailable,
    Other,

    // Loans, Deposits & Syndication
    ConsumerLoans,
    FixedTermDeposits,
    FixedTermLoans,
    MortgageLoans,
    NoticeDeposits,
    NoticeLoans,
    Syndications,

    // Payments
    CounterTransactions,
    CustomerCardTransactions,
    Drafts,
    IssuedCashConcentrationTransactions,
    IssuedCheques,
    IssuedCreditTransfers,
    IssuedDirectDebits,
    IssuedRealTimeCreditTransfers,
    LockboxTransactions,
    MerchantCardTransactions,
    ReceivedCashConcentrationTransactions,
    ReceivedCheques,
    ReceivedCreditTransfers,
    ReceivedDirectDebits,
    ReceivedRealTimeCreditTransfers,

    // Precious Metal
    Options,
    Delivery,
}

impl<'a> ExternalBankTransactionFamily1Code {
    pub(crate) fn parse(reader: &mut XmlReader<'a>, _start: &BytesStart<'_>) -> XmlResult<Self> {
        let value = match &*reader.expect_text()? {
            "ACCB" => Self::AccountBalancing,
            "CAPL" => Self::CashPooling,

            "LFUT" => Self::ListedDerivativesFutures,
            "LOPT" => Self::ListedDerivativesOptions,
            "OBND" => Self::OtcDerivativesBonds,
            "OCRD" => Self::OtcDerivativesCreditDerivatives,
            "OEQT" => Self::OtcDerivativesEquity,
            "OIRT" => Self::OtcDerivativesInterestRates,
            "OSED" => Self::OtcDerivativesStructuredExoticDerivatives,
            "OSWP" => Self::OtcDerivativesSwaps,

            "FWRD" => Self::Forwards,
            "FTUR" => Self::Futures,
            "NDFX" => Self::NonDeliverable,
            "SPOT" => Self::Spots,
            "SWAP" => Self::Swaps,

            "MCOP" => Self::MiscellaneousCreditOperations,
            "MDOP" => Self::MiscellaneousDebitOperations,
            "NTAV" => Self::NotAvailable,
            "OTHR" => Self::Other,

            "CSLN" => Self::ConsumerLoans,
            "FTDP" => Self::FixedTermDeposits,
            "FTLN" => Self::FixedTermLoans,
            "MGLN" => Self::MortgageLoans,
            "NTDP" => Self::NoticeDeposits,
            "NTLN" => Self::NoticeLoans,
            "SYDN" => Self::Syndications,

            "CNTR" => Self::CounterTransactions,
            "CCRD" => Self::CustomerCardTransactions,
            "DRFT" => Self::Drafts,
            "ICCN" => Self::IssuedCashConcentrationTransactions,
            "ICHQ" => Self::IssuedCheques,
            "ICDT" => Self::IssuedCreditTransfers,
            "IDDT" => Self::IssuedDirectDebits,
            "IRCT" => Self::IssuedRealTimeCreditTransfers,
            "LBOX" => Self::LockboxTransactions,
            "MCRD" => Self::MerchantCardTransactions,
            "RCCN" => Self::ReceivedCashConcentrationTransactions,
            "RCHQ" => Self::ReceivedCheques,
            "RCDT" => Self::ReceivedCreditTransfers,
            "RDDT" => Self::ReceivedDirectDebits,
            "RRCT" => Self::ReceivedRealTimeCreditTransfers,

            code => panic!("unhandled code: {code:?}"),
        };
        Ok(value)
    }
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[doc = "Specifies the bank transaction code sub-family, as published in an external bank transaction code sub-family code list.\r\nExternal code sets can be downloaded from www.iso20022.org."]
pub enum ExternalBankTransactionSubFamily1Code {
    Any,
}
impl<'a> ExternalBankTransactionSubFamily1Code {
    pub(crate) fn parse(reader: &mut XmlReader<'a>, _start: &BytesStart<'_>) -> XmlResult<Self> {
        let value = match &*reader.expect_text()? {
            _ => Self::Any,
        };
        Ok(value)
    }
}