// lib/pdf-fill-data/src/randomDataGenerator.js
const { faker } = require('@faker-js/faker');

// Вспомогательные функции
const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const randomFloat = (min, max, decimals) => parseFloat((Math.random() * (max - min) + min).toFixed(decimals));
const formatDate = (date, format = 'MM/DD/YYYY') => {
    const d = new Date(date);
    if (isNaN(d.getTime())) return '';
    const month = String(d.getMonth() + 1).padStart(2, '0');
    const day = String(d.getDate()).padStart(2, '0');
    const year = d.getFullYear();
    if (format === 'Mon DD, YYYY') return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
    if (format === 'Month DD, YYYY') return d.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
    if (format === 'Mon DD') return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
    return `${month}/${day}/${year}`;
};

const generator = {
    /**
     * Генерирует данные для счета AEP Ohio
     */
    aep_ohio: () => {
        const billDate = faker.date.past({ years: 3 });
        const dueDate = new Date(billDate);
        dueDate.setDate(dueDate.getDate() + 22);
        const currentMonth = billDate.getMonth();
        const currentYear = billDate.getFullYear();

        // --- Генерация ключевых и детализированных значений ---
        const usage_current_month = randomInt(3000, 6000);
        const usage_prev_month = randomInt(4000, 7000);
        const usage_prev_year = randomInt(4500, 7500);

        const transmission_service = randomFloat(80, 90, 2);
        const distribution_service = randomFloat(150, 160, 2);
        const customer_charge_detail = randomFloat(20, 25, 2);
        const retail_stability_rider = randomFloat(25, 30, 2);
        const deferred_asset_rider = randomFloat(5, 10, 2);
        const phase_in_recovery_rider = randomFloat(20, 25, 2);
        const power_purchase_rider = randomFloat(0.1, 0.5, 2);
        const supplier_charges = randomFloat(190, 210, 2);
        const late_payment_charge = randomFloat(5, 10, 2);
        const total_amount_due_last_billing = randomFloat(750, 800, 2);

        // --- Расчеты на основе сгенерированных данных ---
        const delivery_charge = transmission_service + distribution_service + customer_charge_detail + retail_stability_rider + deferred_asset_rider + phase_in_recovery_rider + power_purchase_rider;
        const current_charges = delivery_charge + supplier_charges;
        const previous_balance_due = late_payment_charge;
        const amount_due_value = current_charges + previous_balance_due;

        // --- Генерация истории для графика ---
        const history = [];
        const monthNames = ["Aug", "Sep", "Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"];
        let tempDate = new Date(billDate);
        tempDate.setMonth(tempDate.getMonth() - 12);

        for (let i = 0; i < 13; i++) {
            const isWinter = [10, 11, 0, 1].includes(tempDate.getMonth()); // Nov, Dec, Jan, Feb
            let kwh = isWinter ? randomInt(6000, 9000) : randomInt(4000, 6000);

            if (tempDate.getMonth() === currentMonth && tempDate.getFullYear() === currentYear) kwh = usage_current_month;
            if (tempDate.getMonth() === (currentMonth - 1 + 12) % 12 && tempDate.getFullYear() === (currentMonth === 0 ? currentYear - 1 : currentYear)) kwh = usage_prev_month;
            if (tempDate.getMonth() === currentMonth && tempDate.getFullYear() === currentYear - 1) kwh = usage_prev_year;

            history.push({ month: monthNames[i % 12], year: tempDate.getFullYear(), kwh });
            tempDate.setMonth(tempDate.getMonth() + 1);
        }

        return {
            customer_name: faker.person.fullName().toUpperCase(),
            attn_name: `ATTN: ${faker.person.firstName().toUpperCase()} ${faker.person.lastName().toUpperCase()}`,
            service_address_full: `${faker.location.streetAddress()}, ${faker.location.city()}, ${faker.location.state({ abbreviated: true })} ${faker.location.zipCode()}`,
            amount_due_date: formatDate(dueDate, 'Month DD, YYYY'),
            amount_due_value: amount_due_value.toFixed(2),
            bill_mailing_date: formatDate(billDate, 'Aug 8, 2022').replace(/\d+/g, (match) => faker.string.numeric(match.length)), // Генерируем дату в нужном формате, но с рандомными числами
            account_number: faker.finance.accountNumber(10),
            billing_period_from: formatDate(faker.date.recent({days: 35})),
            billing_period_to: formatDate(faker.date.recent({days: 5})),
            billing_period_days: `(${randomInt(28, 32)} days)`,
            current_charges_kwh: usage_current_month.toLocaleString('en-US'),
            remit_pay_after_date_amount: `Pay $${(amount_due_value * 1.01).toFixed(2)} after ${formatDate(dueDate, 'MM/DD/YYYY')}`,
            barcode_number: faker.string.numeric(51),
            total_amount_due_last_billing: total_amount_due_last_billing.toFixed(2),
            payment_thank_you_date: formatDate(faker.date.recent({days: 5})),
            payment_thank_you_amount: `-${total_amount_due_last_billing.toFixed(2)}`,
            late_payment_charge: late_payment_charge.toFixed(2),
            previous_balance_due: previous_balance_due.toFixed(2),
            tariff_info_line: `Tariff ${randomInt(800,900)} - Medium General Service ${formatDate(billDate)}`,
            service_delivery_identifier: faker.string.numeric(17),
            transmission_service: transmission_service.toFixed(2),
            distribution_service: distribution_service.toFixed(2),
            customer_charge_detail: customer_charge_detail.toFixed(2),
            retail_stability_rider: retail_stability_rider.toFixed(2),
            deferred_asset_rider: deferred_asset_rider.toFixed(2),
            phase_in_recovery_rider: phase_in_recovery_rider.toFixed(2),
            power_purchase_rider: power_purchase_rider.toFixed(2),
            supplier_charges: supplier_charges.toFixed(2),
            current_electric_charges_total: delivery_charge.toFixed(2),
            usage_history_data: history,
            total_usage_12_months: `${randomInt(70000, 80000).toLocaleString('en-US')} kWh`,
            avg_monthly_usage: `${randomInt(5500, 6500).toLocaleString('en-US')} kWh`,
            billed_usage_date: formatDate(billDate, 'MM/YY'),
            billed_usage_kwh_usage: usage_current_month.toLocaleString('en-US'),
            billed_usage_kwh_billed: `${usage_current_month.toLocaleString('en-US')} kWh`,
            billed_usage_kw_usage: randomFloat(15, 20, 3).toString(),
            billed_usage_kw_billed: `${randomFloat(15, 20, 3)} kW`,
            meter_read_details_meter_no: faker.string.numeric(8),
            meter_read_kwh_current: randomInt(90000, 95000).toString(),
            meter_read_kwh_previous: (90000 - usage_current_month).toString(),
            meter_read_kwh_metered: usage_current_month.toString(),
            meter_read_kwh_usage: `${usage_current_month.toLocaleString('en-US')} kWh`,
            meter_read_kw_current: randomFloat(15, 20, 3).toString(),
            meter_read_kw_metered: randomFloat(15, 20, 3).toString(),
            meter_read_kw_usage: `${randomFloat(15, 20, 3)} kW`,
            meter_read_service_period: `${formatDate(faker.date.recent({days: 35}), 'MM/DD')} - ${formatDate(faker.date.recent({days: 5}), 'MM/DD')}`,
            next_read_date_info: `Next scheduled read date should be between ${formatDate(faker.date.soon({days: 10}), 'Mon DD')} and ${formatDate(faker.date.soon({days: 15}), 'Mon DD')}.`,
            area_office: faker.string.numeric(5),
            cashier_number: faker.string.numeric(3),
            deposit_number: `${faker.string.numeric(9)} ${faker.string.numeric(4)} ${faker.string.numeric(3)} ${formatDate(billDate, 'YYYYMMDD')}`,
            deposit_date: formatDate(billDate),
            deposit_amount: `$${randomFloat(150, 200, 2)}`,
        };
    },

    /**
     * Генерирует данные для счета Entergy
     */
    entergy: () => {
        const mailDate = faker.date.past({ years: 2 });
        const dueDate = new Date(mailDate);
        dueDate.setDate(dueDate.getDate() + 23);
        const currentMonthIndex = mailDate.getMonth();
        const firstName = faker.person.firstName();
        const lastName = faker.person.lastName();

        const history = Array.from({ length: 12 }, (_, i) => {
            const monthName = new Date(2000, i).toLocaleString('en-US', { month: 'short' }).toUpperCase();
            let kwh = 0;
            if (i <= currentMonthIndex) {
                const isSummer = i >= 4 && i <= 7;
                kwh = isSummer ? randomInt(2000, 3000) : randomInt(800, 1800);
            }
            return { month: monthName, kwh };
        });

        const kwh_used = history[currentMonthIndex].kwh;
        const plan = randomFloat(80, 150, 2), fuel = randomFloat(40, 70, 2), other = randomFloat(15, 50, 2);
        const totalDue = plan + fuel + other;

        return {
            customer_name: firstName,
            mail_date: formatDate(mailDate),
            account_number: faker.finance.accountNumber(9),
            invoice_number: faker.finance.accountNumber(11),
            amount_due_by_date: formatDate(dueDate),
            amount_due_after_date: formatDate(dueDate),
            amount_due_after_value: `$${(totalDue * 1.05).toFixed(2)}`,
            service_location_line1: faker.location.streetAddress(),
            service_location_line2: `${faker.location.city()}, ${faker.location.state({ abbreviated: true })} ${faker.location.zipCode()}`,
            billing_days: randomInt(28, 32),
            kwh_used,
            avg_kwh_per_day: (kwh_used / 30).toFixed(1),
            remit_customer_address: `${firstName.toUpperCase()} ${lastName.toUpperCase()}\n${faker.location.streetAddress()}\n${faker.location.city()}, ${faker.location.state({ abbreviated: true })} ${faker.location.zipCode()}`,
            barcode_number: faker.string.numeric(50),
            usage_history_data: history,
            qpc_code: faker.string.numeric(5),
            cycle_number: randomInt(1, 25),
            energy_charge: (plan * 0.9).toFixed(2),
            federal_eac_rider: (plan * 0.1).toFixed(2),
            fuel_adjustment: fuel.toFixed(2),
            storm_restoration_offset: (other * -0.1).toFixed(2),
            storm_restoration_charge: (other * 1.1).toFixed(2),
            deposit: "0.00",
            connect_fee: "0.00"
        };
    },

    /**
     * Генерирует данные для счета Verizon
     */
    verizon: () => {
        const activation_fee = 35.00;
        const plan_ultimate = 100.00;
        const perk_apple_one = 10.00;
        const surcharge_fus = randomFloat(5, 8, 2);
        const surcharge_regulatory = randomFloat(0.1, 0.5, 2);
        const surcharge_admin = randomFloat(3, 4, 2);
        const tax_911 = 1.50;
        const tax_ga_state = randomFloat(2, 3, 2);
        const tax_fulton_county = randomFloat(2, 3, 2);
        const dueDate = faker.date.future({ years: 1 });
        
        return {
            account_number: `${faker.string.numeric(9)}-00001`,
            invoice_number: faker.string.numeric(10),
            customer_name: faker.person.fullName().toUpperCase(),
            customer_address: faker.location.streetAddress(),
            customer_city_st_zip: `${faker.location.city()}, ${faker.location.state({ abbreviated: true })} ${faker.location.zipCode()}`,
            total_due_date: formatDate(dueDate, 'Mon DD'),
            full_due_date: formatDate(dueDate, 'Month DD, YYYY'),
            bill_month: dueDate.toLocaleString('en-US', { month: 'long' }),
            payment_received: '$0.00',
            barcode_number: faker.string.numeric(52),
            activation_fee: activation_fee.toFixed(2),
            plan_ultimate: plan_ultimate.toFixed(2),
            perk_apple_one: perk_apple_one.toFixed(2),
            surcharge_fus: surcharge_fus.toFixed(2),
            surcharge_regulatory: surcharge_regulatory.toFixed(2),
            surcharge_admin: surcharge_admin.toFixed(2),
            tax_911: tax_911.toFixed(2),
            tax_ga_state: tax_ga_state.toFixed(2),
            tax_fulton_county: tax_fulton_county.toFixed(2)
        };
    },

    /**
     * Генерирует данные для счета PG&E
     */
    pge: () => {
        // --- 1. Базовые случайные параметры для всего счета ---
        const statementDate = faker.date.past({ years: 2 });
        const dueDate = new Date(statementDate);
        dueDate.setDate(dueDate.getDate() + 21);
        const billing_days = randomInt(28, 31);

        // --- 2. Генерируем данные для графика "Electric Usage This Period" (стр. 3) ---
        const daily_electric_usage_history = [];
        let total_kwh = 0;
        for (let i = 0; i < billing_days; i++) {
            const dayKwh = randomFloat(8, 25, 2);
            total_kwh += dayKwh;
            daily_electric_usage_history.push({ day: '', kwh: dayKwh });
        }
        const average_daily_usage = total_kwh / billing_days;

        // --- 3. Генерируем данные для графика "Gas Usage This Period" (стр. 5) ---
        const daily_gas_usage_history = [];
        let total_therms = 0;
        for (let i = 0; i < billing_days; i++) {
            let thermValue = 0;
            if (Math.random() < 0.3) { // Вероятность потребления газа в день ~30%
                thermValue = randomFloat(0.5, 1.8, 2);
                total_therms += thermValue;
            }
            daily_gas_usage_history.push({ day: '', gas: thermValue });
        }
        const gas_average_daily_usage = total_therms > 0 ? total_therms / billing_days : 0;

        // --- 4. Рассчитываем итоговые суммы на основе сгенерированных данных ---
        // Детализация Electric Charges (стр. 2)
        const electric_conservation_incentive = -randomFloat(5, 10, 2);
        const electric_transmission = randomFloat(10, 15, 2);
        const electric_distribution = randomFloat(30, 40, 2);
        const electric_public_purpose = randomFloat(4, 6, 2);
        const electric_nuclear_decommissioning = randomFloat(0.2, 0.5, 2);
        const electric_dwr_bond = randomFloat(1, 3, 2);
        const electric_ctc = randomFloat(0.3, 0.6, 2);
        const electric_ecra = -randomFloat(0.1, 0.4, 2);
        const electric_pcia = randomFloat(8, 12, 2);
        const electric_taxes_and_other = randomFloat(0.2, 0.3, 2);
        const pge_delivery_charges_num = electric_conservation_incentive + electric_transmission + electric_distribution + 
                                       electric_public_purpose + electric_nuclear_decommissioning + electric_dwr_bond + 
                                       electric_ctc + electric_ecra + electric_pcia + electric_taxes_and_other;
        
        // Детализация SVCE Charges (стр. 4)
        const svce_generation_charges_num = randomFloat(30, 40, 2);
        
        const total_amount_due_num = pge_delivery_charges_num + svce_generation_charges_num;
        const previous_statement_num = randomFloat(total_amount_due_num * 0.9, total_amount_due_num * 1.1, 2);


        return {
            // --- Основные данные ---
            account_no: `${faker.finance.accountNumber(10)}-${randomInt(1,9)}`,
            statement_date: formatDate(statementDate),
            due_date: formatDate(dueDate),
            service_for_name: faker.person.fullName().toUpperCase(),
            service_for_address: `${faker.location.buildingNumber()} ${faker.location.street()}`,
            
            // --- Account Summary (стр. 1) ---
            previous_statement: `${previous_statement_num.toFixed(2)}`,
            payment_received: `-${previous_statement_num.toFixed(2)}`,
            previous_unpaid_balance: '0.00',
            pge_delivery_charges: `${pge_delivery_charges_num.toFixed(2)}`,
            svce_generation_charges: `${svce_generation_charges_num.toFixed(2)}`,
            total_amount_due_date: formatDate(dueDate),
            total_amount_due: `${total_amount_due_num.toFixed(2)}`,
            
            // --- Remittance Slip (стр. 1) ---
            remit_account_number: `${faker.finance.accountNumber(9)}-1`,
            remit_due_date: formatDate(dueDate),
            remit_total_amount_due: `${total_amount_due_num.toFixed(2)}`,
            
            // --- Данные для графиков (стр. 1, 3, 5) ---
            monthly_billing_history: Array.from({length: 13}, () => ({ month: faker.date.month({abbreviated: true}), electric: randomInt(70, 140), gas: randomInt(10, 60) })),
            daily_electric_usage_history: daily_electric_usage_history,
            daily_gas_usage_history: daily_gas_usage_history,
            average_daily_usage: average_daily_usage.toFixed(2),
            gas_average_daily_usage: gas_average_daily_usage.toFixed(2),
            daily_usage_gas: { year_ago: randomFloat(12, 13, 2).toFixed(2), last_period: randomFloat(12, 13, 2).toFixed(2), current_period: randomFloat(12, 13, 2).toFixed(2) },
            daily_usage_electric: { year_ago: randomFloat(0.1, 0.2, 2).toFixed(2), last_period: randomFloat(0.1, 0.2, 2).toFixed(2), current_period: randomFloat(0.1, 0.2, 2).toFixed(2) },

            // --- Детализация Electric Charges (стр. 2) ---
            electric_conservation_incentive: `-${Math.abs(electric_conservation_incentive).toFixed(2)}`,
            electric_transmission: electric_transmission.toFixed(2),
            electric_distribution: electric_distribution.toFixed(2),
            electric_public_purpose: electric_public_purpose.toFixed(2),
            electric_nuclear_decommissioning: electric_nuclear_decommissioning.toFixed(2),
            electric_dwr_bond: electric_dwr_bond.toFixed(2),
            electric_ctc: electric_ctc.toFixed(2),
            electric_ecra: `-${Math.abs(electric_ecra).toFixed(2)}`,
            electric_pcia: electric_pcia.toFixed(2),
            electric_taxes_and_other: electric_taxes_and_other.toFixed(2),
            electric_total_charges: `${pge_delivery_charges_num.toFixed(2)}`,
            
            // --- Детализация (стр. 3) ---
            delivery_charges_period: `${formatDate(faker.date.recent({days: 35}))} - ${formatDate(faker.date.recent({days: 5}))} (${billing_days} billing days)`,
            service_agreement_id: faker.string.numeric(9),
            rate_schedule: `E${randomInt(1,6)} X Residential Service`,
            meter_number: faker.string.numeric(10),
            current_meter_reading: randomInt(30000, 40000).toLocaleString('en-US'),
            prior_meter_reading: randomInt(28000, 29999).toLocaleString('en-US'),
            total_usage_kwh: `${total_kwh.toFixed(6)} kWh`,
            baseline_territory: faker.helpers.arrayElement(['X', 'Y', 'Z']),
            heat_source: 'B - Not Electric',
            tier1_allowance_detail: `${randomFloat(290, 310, 2)} kWh (${billing_days} days x ${randomFloat(9, 11, 1)} kWh/day)`,
            tier1_usage_amount: `${randomFloat(60, 70, 2)}`,
            tier2_usage_amount: `${randomFloat(20, 30, 2)}`,
            generation_credit: `-${randomFloat(40, 50, 2)}`,
            pcia_adjustment: `${randomFloat(10, 15, 2)}`,
            franchise_fee_surcharge: `0.${randomInt(20,30)}`,
            electric_usage_period_title: `Electric Usage This Period: ${total_kwh.toFixed(6)} kWh, ${billing_days} billing days`,

            // --- Детализация (стр. 4) ---
            svce_rate_schedule: 'E-1',
            svce_generation_detail: `${total_kwh.toFixed(6)} kWh @ ${(svce_generation_charges_num / total_kwh).toFixed(5)}`,
            svce_generation_amount: `${(svce_generation_charges_num * 0.99).toFixed(2)}`,
            svce_energy_surcharge: (svce_generation_charges_num * 0.01).toFixed(2),
            svce_total_charges: `${svce_generation_charges_num.toFixed(2)}`,
            
            // --- Детализация (стр. 5) ---
            gas_charges_period: `${formatDate(faker.date.recent({days: 35}))} - ${formatDate(faker.date.recent({days: 5}))} (${billing_days} billing days)`,
            gas_service_agreement_id: faker.string.numeric(10),
            gas_rate_schedule: `G1 X Residential Service`,
            gas_meter_number: faker.string.numeric(8),
            gas_current_reading: randomInt(2500, 2600).toLocaleString('en-US'),
            gas_prior_reading: randomInt(2400, 2499).toLocaleString('en-US'),
            gas_difference: randomInt(2, 10).toString(),
            gas_multiplier: randomFloat(1, 1.1, 6).toString(),
            gas_total_usage: `${total_therms.toFixed(6)} Therms`,
            gas_baseline_territory: 'X',
            gas_serial: 'G',
            gas_tier1_allowance_detail: `${randomFloat(15, 20, 2)} Therms (${billing_days} days x 0.59 Therms/day)`,
            gas_tier1_usage_detail: `${total_therms.toFixed(6)} Therms @ ${randomFloat(1, 1.5, 5)}`,
            gas_tier1_usage_amount: `${randomFloat(5, 8, 2)}`,
            gas_ppp_surcharge_detail: `($0.0${randomInt(9000, 9999)} /Therm)`,
            gas_ppp_surcharge_amount: `0.${randomInt(40, 50)}`,
            gas_total_charges: `${randomFloat(6, 9, 2)}`,
            gas_procurement_period: `${formatDate(faker.date.recent({days: 65}))} - ${formatDate(faker.date.recent({days: 35}))}`,
            gas_procurement_amount: `$0.${randomInt(25000, 30000)}`,
            gas_usage_period_title: `Gas Usage This Period: ${total_therms.toFixed(6)} Therms, ${billing_days} billing days`
        };
    }
};

module.exports = generator;