const pdfFillData = require('./pdfFillData');

class pdfFillDataXfinity extends pdfFillData {

    constructor() {
        super('Xfinity');

        this.customer_name = '';
        this.account_number = '';
        this.billing_date = '';
        this.address = '';
        this.plan = '';
        this.speed = '';

        this.customer_name_address = '';
        this.services_from = '';
        this.credit_card_payment_thank_you = '';
        this.credit_card_payment_thank_you_Y = '';
        this.automatic_payment = '';
        this.tarif = '';
        this.your_package = '';
        this.equipment = "$14.00";
        this.peacock_premium = "$0.00";
        this.balance_forward = "$0.00";
        this.regular_monthly_charges = '';
        this.regular_monthly_charges_d = '';
        this.other_charges = '';
        this.totalD = '';
        this.total = '';
        this.previous_balance = '';
        this.new_charges = '';
        this.amount_due = '';
        this.credit_card_payment = '';
        this.totalS7 = '';
        this.code_number = '';
        this.automatic_payment_lines = '';
        this.fontSize = 9;
        this.lineHeight = 0;
        this.yPosition = 0;
        this.rightMargin = 0;
        this.rightMarginBold = 0;
        this.rightMarginBoldV = 0;
        this.customer_name_address_lines = '';
        this.fontSize2 = 8;
        this.lineHeight2 = 0;
        this.yPosition2 = 0;
        this.rightMargin3 = 0;
        this.rightMargin3M = 0;

        this.dataMap = [];
    }

    async setFields(fields) {
        // base
        this.customer_name = fields.customer_name;
        this.account_number = fields.account_number;
        this.billing_date = fields.billing_date;
        this.address = fields.address;
        this.plan = fields.plan;
        this.speed = fields.speed;

        // other
        this.customer_name_address = this.customer_name.toUpperCase() + "\n" + this.splitAddress(this.address);
        this.services_from = this.getServicePeriod(this.billing_date);
        this.credit_card_payment_thank_you = this.getCreditCardPaymentDate(this.billing_date);
        this.credit_card_payment_thank_you_Y = this.getCreditCardPaymentDateY(this.billing_date);
        this.automatic_payment = this.calculateAutoPaymentDate(this.credit_card_payment_thank_you_Y);
        this.tarif = this.getPriceByAddress(this.plan, this.address, this.getSocrCache(), this.getTariffsCache());
        this.your_package = this.tarif.price.replace('/mo.','');
        this.regular_monthly_charges = parseFloat(this.your_package.replace('$', '')) + parseFloat(this.equipment.replace('$', ''));
        this.regular_monthly_charges_d = this.regular_monthly_charges.toFixed(2);
        this.regular_monthly_charges = "$" + this.regular_monthly_charges_d;
        this.other_charges = await this.getTaxRateByAddress(this.address);
        this.other_charges = "$" + (this.regular_monthly_charges_d * (parseFloat(this.other_charges.details.rate.combined_rate).toFixed(2) * 100) / 100).toFixed(2);
        this.totalD = parseFloat(this.regular_monthly_charges.replace('$', '')) + parseFloat(this.other_charges.replace('$', ''));
        this.total = "$" + this.totalD.toFixed(2);
        this.previous_balance = this.total;
        this.new_charges = this.total;
        this.amount_due = this.total;
        this.credit_card_payment = '-' + this.total;
        this.totalS7 = Math.floor(this.totalD * 100).toString().padStart(7, '0');
        this.code_number = String(this.account_number.replaceAll(" ",'')) + this.totalS7;
        this.code_number += this.hashWeightCodeNumber(this.code_number);
        this.automatic_payment_lines = `Your automatic payment on ${this.automatic_payment || ''}, will include your\namount due, plus or minus any payment related activities or\nadjustments, and less any credits issued before your bill due\ndate.`.split('\n');
        this.lineHeight = this.fontSize * 1.0;
        this.yPosition = this.pixelsToPoints(1682, 300);
        this.rightMargin = this.pixelsToPoints(1393, 300);
        this.rightMarginBold = this.pixelsToPoints(1395, 300);
        this.rightMarginBoldV = this.pixelsToPoints(1396, 300);
        this.customer_name_address_lines = `${this.customer_name_address || ''}`.split('\n');
        this.lineHeight2 = this.fontSize2 * 1.075;
        this.yPosition2 = this.pixelsToPoints(627, 300);
        this.rightMargin3 = this.pixelsToPoints(1128, 300);
        this.rightMargin3M = this.pixelsToPoints(1103, 300);
    }

    splitAddress(address) {
        const words = address.split(", ");
        const total = words[0] + "\n" + words[1] + ", " + words[2] + " " + words[3];

        return total;
    }

    getServicePeriod(billingDateStr) {

        const billingDate = new Date(billingDateStr);
        const firstDate = new Date(billingDate);
        const dayOfWeek = firstDate.getDay();
        const daysToMonday = dayOfWeek === 0 ? 1 : dayOfWeek === 1 ? 0 : 8 - dayOfWeek;
        firstDate.setDate(firstDate.getDate() + daysToMonday);

        const secondDate = new Date(billingDate);
        secondDate.setMonth(secondDate.getMonth() + 1);
        secondDate.setDate(secondDate.getDate() - 1);

        const options = { month: 'short', day: 'numeric', year: 'numeric' };
        const firstDateStr = firstDate.toLocaleDateString('en-US', options);
        const secondDateStr = secondDate.toLocaleDateString('en-US', options);

        return `${firstDateStr} to ${secondDateStr}`;
    }

    getCreditCardPaymentDate(billingDate) {
        return super.getCreditCardPaymentDate(billingDate);
    }

    getCreditCardPaymentDateY(billingDate) {
        let date = new Date(billingDate);

        date.setDate(date.getDate() - 7);

        if (date.getDay() === 0) {
            date.setDate(date.getDate() - 1);
        }

        const options = { month: 'short', day: 'numeric', year: 'numeric' };
        return date.toLocaleDateString('en-US', options);
    }

    calculateAutoPaymentDate(billingDate) {
        let date = new Date(billingDate);
        date.setMonth(date.getMonth() + 1);
        date.setDate(date.getDate() - 1);

        while (date.getDay() === 0) {
            date.setDate(date.getDate() - 1);
        }

        const options = { month: 'short', day: '2-digit', year: 'numeric' };
        return date.toLocaleDateString('en-US', options);
    }

    getPriceByAddress(plan, address, abbreviations, tariffs) {
        const stateCode = address.split(',')[2].trim().split(' ')[0];
        const stateInfo = abbreviations.find(item => item.ABBREVIATION === stateCode);
        if (!stateInfo) {
            throw new Error(`State with abbreviation ${stateCode} not found`);
        }
        const stateName = stateInfo["STATE(TERRITORY)"];

        for (const tariff of tariffs) {
            const statesInTariff = tariff.States.split(', ').map(s => s.trim());
            if (statesInTariff.includes(stateName) && tariff.Plan == plan) {
                return {
                    state: stateName,
                    region: tariff.Region,
                    plan: tariff.Plan,
                    price: tariff.Price
                };
            }
        }

        throw new Error(`No tariff found for state ${stateName}`);
    }

    hashWeightCodeNumber(code_number) {
        const weights = [7, 3, 1];

        const sum = code_number
            .split('')
            .reduce((acc, char, index) => {
                const digit = parseInt(char, 10);
                const weight = weights[index % 3];
                return acc + digit * weight;
            }, 0);

        return sum % 10;
    }

    pixelsToPoints(pixels, dpi = 72) {
        return super.pixelsToPoints(pixels, dpi);
    }

    async alignTextToRight(ipage, ifont, setFontSize, setRightMargin, setText) {
        return await super.alignTextToRight(ipage, ifont, setFontSize, setRightMargin, setText);
    }

    async draw() {

        this.dataMap = [
            {
                ipage: 0,
                field: this.customer_name + ',',
                x: this.pixelsToPoints(340, 300),
                y: this.pixelsToPoints(2810, 300),
                size: 20,
                ifont: 3,
                cR: 0.313,
                cG: 0.309,
                cB: 0.631,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.account_number,
                x: this.pixelsToPoints(1006, 300),
                y: this.pixelsToPoints(3094, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.billing_date,
                x: this.pixelsToPoints(1426, 300),
                y: this.pixelsToPoints(3094, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.services_from,
                x: this.pixelsToPoints(1726, 300),
                y: this.pixelsToPoints(3094, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.address,
                x: this.pixelsToPoints(196, 300),
                y: this.pixelsToPoints(2434, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.credit_card_payment_thank_you,
                x: this.pixelsToPoints(721, 300),
                y: this.pixelsToPoints(2279, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.previous_balance,
                x: await this.alignTextToRight(0, 1, 8, this.rightMargin, `${this.previous_balance || ''}`),
                y: this.pixelsToPoints(2349, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.credit_card_payment,
                x: await this.alignTextToRight(0, 1, 8, this.rightMargin, `${this.credit_card_payment || ''}`),
                y: this.pixelsToPoints(2275, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.balance_forward,
                x: await this.alignTextToRight(0, 3, 9, this.rightMarginBold, `${this.balance_forward || ''}`),
                y: this.pixelsToPoints(2207, 300),
                size: 9,
                ifont: 3,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.regular_monthly_charges,
                x: await this.alignTextToRight(0, 1, 8, this.rightMargin, `${this.regular_monthly_charges || ''}`),
                y: this.pixelsToPoints(2111, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.other_charges,
                x: await this.alignTextToRight(0, 1, 8, this.rightMargin, `${this.other_charges || ''}`),
                y: this.pixelsToPoints(2041, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.new_charges,
                x: await this.alignTextToRight(0, 3, 9, this.rightMarginBold, `${this.new_charges || ''}`),
                y: this.pixelsToPoints(1971, 300),
                size: 9,
                ifont: 3,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.amount_due,
                x: await this.alignTextToRight(0, 3, 12, this.rightMarginBoldV, `${this.amount_due || ''}`),
                y: this.pixelsToPoints(1840, 300),
                size: 12,
                ifont: 3,
                cR: 1,
                cG: 1,
                cB: 1,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.account_number,
                x: this.pixelsToPoints(1916, 300),
                y: this.pixelsToPoints(928, 300),
                size: 11,
                ifont: 3,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.automatic_payment,
                x: this.pixelsToPoints(1916, 300),
                y: this.pixelsToPoints(863, 300),
                size: 11,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.amount_due,
                x: this.pixelsToPoints(1916, 300),
                y: this.pixelsToPoints(771, 300),
                size: 16,
                ifont: 3,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.automatic_payment,
                x: this.pixelsToPoints(1970, 300),
                y: this.pixelsToPoints(668, 300),
                size: 9,
                ifont: 3,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 0,
                field: this.code_number,
                x: this.pixelsToPoints(137, 300),
                y: this.pixelsToPoints(135, 300),
                size: 11.5,
                ifont: 4,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 1,
                field: this.account_number,
                x: this.pixelsToPoints(1006, 300),
                y: this.pixelsToPoints(3094, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 1,
                field: this.billing_date,
                x: this.pixelsToPoints(1426, 300),
                y: this.pixelsToPoints(3094, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 1,
                field: this.services_from,
                x: this.pixelsToPoints(1726, 300),
                y: this.pixelsToPoints(3094, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.account_number,
                x: this.pixelsToPoints(1006, 300),
                y: this.pixelsToPoints(3094, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.billing_date,
                x: this.pixelsToPoints(1426, 300),
                y: this.pixelsToPoints(3094, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.services_from,
                x: this.pixelsToPoints(1726, 300),
                y: this.pixelsToPoints(3094, 300),
                size: 8,
                ifont: 2,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.regular_monthly_charges,
                x: await this.alignTextToRight(2, 3, 12, this.rightMargin3, `${this.regular_monthly_charges || ''}`),
                y: this.pixelsToPoints(2877, 300),
                size: 14,
                ifont: 3,
                cR: 0.313,
                cG: 0.309,
                cB: 0.631,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.your_package,
                x: await this.alignTextToRight(2, 3, 10, this.rightMargin3M, `${this.your_package || ''}`),
                y: this.pixelsToPoints(2775, 300),
                size: 10,
                ifont: 3,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.plan,
                x: this.pixelsToPoints(282, 300),
                y: this.pixelsToPoints(2702, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.your_package,
                x: await this.alignTextToRight(2, 1, 8, this.rightMargin3M, `${this.your_package || ''}`),
                y: this.pixelsToPoints(2702, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.peacock_premium,
                x: await this.alignTextToRight(2, 1, 8, this.rightMargin3M, `${this.peacock_premium || ''}`),
                y: this.pixelsToPoints(2702, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.speed,
                x: this.pixelsToPoints(1924, 300),
                y: this.pixelsToPoints(2775, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.equipment,
                x: await this.alignTextToRight(2, 3, 10, this.rightMargin3M, `${this.equipment || ''}`),
                y: this.pixelsToPoints(2172, 300),
                size: 10,
                ifont: 3,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.equipment,
                x: await this.alignTextToRight(2, 1, 8, this.rightMargin3M, `${this.equipment || ''}`),
                y: this.pixelsToPoints(1962, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.other_charges,
                x: await this.alignTextToRight(2, 3, 12, this.rightMargin3, `${this.other_charges || ''}`),
                y: this.pixelsToPoints(1826, 300),
                size: 14,
                ifont: 3,
                cR: 0.313,
                cG: 0.309,
                cB: 0.631,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.other_charges,
                x: await this.alignTextToRight(2, 3, 10, this.rightMargin3M, `${this.other_charges || ''}`),
                y: this.pixelsToPoints(1722, 300),
                size: 10,
                ifont: 3,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            },
            {
                ipage: 2,
                field: this.other_charges,
                x: await this.alignTextToRight(2, 1, 8, this.rightMargin3M, `${this.other_charges || ''}`),
                y: this.pixelsToPoints(1647, 300),
                size: 8,
                ifont: 1,
                cR: 0,
                cG: 0,
                cB: 0,
                encoding: 'utf-8'
            }
        ];

        for(let idm in this.dataMap) {
            await super.draw(
                this.dataMap[idm].ipage,
                this.dataMap[idm].field,
                this.dataMap[idm].x,
                this.dataMap[idm].y,
                this.dataMap[idm].size,
                this.dataMap[idm].ifont,
                this.dataMap[idm].cR,
                this.dataMap[idm].cG,
                this.dataMap[idm].cB,
                this.dataMap[idm].encoding
            );
        }

        this.automatic_payment_lines.forEach((line, index) => {
            super.draw(
                0,
                line,
                this.pixelsToPoints(113, 300),
                (this.yPosition - (index * this.lineHeight)),
                this.fontSize,
                2,
                0,
                0,
                0,
                'utf-8'
            );
        });

        this.customer_name_address_lines.forEach((line, index) => {
            super.draw(
                0,
                line,
                this.pixelsToPoints(137, 300),
                (this.yPosition2 - (index * this.lineHeight2)),
                this.fontSize2,
                2,
                0,
                0,
                0,
                'utf-8'
            );
        });

    }

    async saveData(host, outputDir) {
        return await super.saveData(host, outputDir, 'Xfinity' );
    }
}

module.exports = pdfFillDataXfinity;