const TagLengthString = require("../tagLengthString");
const { emv, errorCode } = require("../constant");
const { KHQRResponse } = require("../model");

// tag should be 29, 30
class GlobalUniqueIdentifier extends TagLengthString {
    constructor(tag, valueObject) {
        if (valueObject == null)
            throw KHQRResponse(null, errorCode.MERCHANT_TYPE_REQUIRED);

        if (valueObject == null)
            valueObject = {
                bakongAccountID: null,
                merchantID: null,
                acquiringBank: null,
                accountInformation: null,
            };

        // Get value from props object
        const bakongAccountID = valueObject.bakongAccountID;
        const merchantID = valueObject.merchantID;
        const acquiringBank = valueObject.acquiringBank;

        const isMerchant = valueObject.isMerchant;
        const accountInformation = valueObject.accountInformation;

        // Creating 3 instances
        // BakongAccountID: 00
        // MerchantID: 01
        // AcquiringBankName: 02
        const bakongAccountId = new BakongAccountID(
            emv.BAKONG_ACCOUNT_IDENTIFIER,
            bakongAccountID
        );

        let globalUniqueIdentifier = bakongAccountId.toString();

        if (isMerchant) {
            const merchantId = new MerchantId(
                emv.MERCHANT_ACCOUNT_INFORMATION_MERCHANT_ID,
                merchantID
            );
            const acquiringBankName = new AcquiringBank(
                emv.MERCHANT_ACCOUNT_INFORMATION_ACQUIRING_BANK,
                acquiringBank
            );


            if (merchantID != undefined)
                globalUniqueIdentifier += merchantId.toString();
            if (acquiringBank != undefined)
                globalUniqueIdentifier += acquiringBankName.toString();

            super(tag, globalUniqueIdentifier);

            this.merchantID = merchantId;
            this.acquiringBank = acquiringBankName;
            this.data = {
                bakongAccountID: bakongAccountId,
                merchantID: merchantId,
                acquiringBank: acquiringBankName,
            };
        } else {
            if (accountInformation != undefined) {
                const accInformation = new AccountInformation(
                    emv.INDIVIDUAL_ACCOUNT_INFORMATION,
                    accountInformation
                );
                globalUniqueIdentifier += accInformation.toString();
            }

            if (acquiringBank != undefined) {
                const acquiringBankName = new AcquiringBank(
                    emv.MERCHANT_ACCOUNT_INFORMATION_ACQUIRING_BANK,
                    acquiringBank
                );
                globalUniqueIdentifier += acquiringBankName.toString();
            }

            super(tag, globalUniqueIdentifier);

            this.accountInformation = accountInformation;
            this.data = {
                bakongAccountID: bakongAccountId,
                accountInformation: accountInformation,
            };
        }
        this.bakongAccountID = bakongAccountId;
    }
}

class BakongAccountID extends TagLengthString {
    constructor(tag, bakongAccountID) {
        // Throw validation if there is
        // 1. No tag
        // 2. empty value of bakong account
        if (
            bakongAccountID == "" ||
            bakongAccountID == null ||
            bakongAccountID == undefined
        )
            throw KHQRResponse(null, errorCode.BAKONG_ACCOUNT_ID_REQUIRED);

        // Validating the bakong account is it is correct
        // name@bank_domain
        const bakongAccountDivide = bakongAccountID.split("@");

        // Validate on length of the bakong account
        if (bakongAccountID.length > emv.INVALID_LENGTH.BAKONG_ACCOUNT)
            throw KHQRResponse(
                null,
                errorCode.BAKONG_ACCOUNT_ID_LENGTH_INVALID
            );
        else if (bakongAccountDivide.length < 2)
            throw KHQRResponse(null, errorCode.BAKONG_ACCOUNT_ID_INVALID);
        super(tag, bakongAccountID);
    }
}

class AccountInformation extends TagLengthString {
    constructor(tag, value) {
        if (value.length > emv.INVALID_LENGTH.ACCOUNT_INFORMATION)
            throw KHQRResponse(null, errorCode.ACCOUNT_INFORMATION_LENGTH_INVALID);
        super(tag, value)
    }
}

class MerchantId extends TagLengthString {
    constructor(tag, value) {
        if (value == "" || value == null || value == undefined)
            throw KHQRResponse(null, errorCode.MERCHANT_ID_REQUIRED);
        else if (value.length > emv.INVALID_LENGTH.MERCHANT_ID)
            throw KHQRResponse(null, errorCode.MERCHANT_ID_LENGTH_INVALID);
        super(tag, value);
    }
}

class AcquiringBank extends TagLengthString {
    constructor(tag, value) {
        if (value == "" || value == null || value == undefined)
            throw KHQRResponse(null, errorCode.ACQUIRING_BANK_REQUIRED);
        else if (value.length > emv.INVALID_LENGTH.ACQUIRING_BANK)
            throw KHQRResponse(null, errorCode.ACQUIRING_BANK_LENGTH_INVALID);
        super(tag, value);
    }
}

module.exports = GlobalUniqueIdentifier;
