// File: report.js (Versi Final yang Sudah Diperbaiki)

String.prototype.center = function(width, char = ' ') {
    if (!this || width < this.length) return this;
    const padding = Math.max(0, width - this.length);
    const left = Math.floor(padding / 2);
    const right = padding - left;
    return char.repeat(left) + this + char.repeat(right);
};

async function generateReport(options) {
    // Opsi default
    const defaultOptions = {
        startDate: new Date().toISOString().slice(0, 10),
        endDate: new Date().toISOString().slice(0, 10),
        kasir: 'All',
        registerNomor: null,
        saldoAkhir: 0, // Tambahkan saldoAkhir untuk laporan tutup kasir
        brand: typeof xbrand !== 'undefined' ? xbrand : '001',
        cab: typeof xcab !== 'undefined' ? xcab : '002',
        posSettings: {} // Siapkan untuk menerima data pos dari Vue
    };
    const opts = { ...defaultOptions, ...options };

    try {
        // Ambil pengaturan POS dari database sebagai fallback
        const posQuery = `SELECT * FROM pos WHERE brand='${opts.brand}' AND cab='${opts.cab}'`;
        const posData = JSON.parse(await ambil_select('pos', posQuery));
        const dbPosSettings = {};
        posData.forEach(p => { dbPosSettings[p.kode] = p.isi; });

        // Gabungkan pengaturan dari Vue (prioritas utama) dengan fallback dari DB
        const finalPosSettings = { ...dbPosSettings, ...opts.posSettings };

        // Logika pengambilan data (tidak berubah)
        let jualQuery = `SELECT * FROM jual WHERE brand='${opts.brand}' AND cab='${opts.cab}' AND batal != '1'`;
        if (opts.registerNomor) {
            jualQuery += ` AND register = '${opts.registerNomor}'`;
        } else {
            jualQuery += ` AND tanggal >= '${opts.startDate}' AND tanggal <= '${opts.endDate}'`;
            if (opts.kasir !== 'All') {
                jualQuery += ` AND kasir = '${opts.kasir}'`;
            }
        }
        
        const jualData = JSON.parse(await ambil_select('jual', jualQuery));
        
        let registerData = null;
        if(opts.registerNomor) {
            const registerQuery = `SELECT * FROM register WHERE nomor = '${opts.registerNomor}'`;
            const registerResult = JSON.parse(await ambil_select('register', registerQuery));
            if(registerResult.length > 0) {
                registerData = registerResult[0];
            }
        }

        const nomorList = jualData.map(j => `'${j.nomor}'`).join(',');
        const pesaniQuery = nomorList ? `SELECT * FROM pesani WHERE nomor IN (${nomorList})` : '';
        const pesaniData = pesaniQuery ? JSON.parse(await ambil_select('pesani', pesaniQuery)) : [];
        
        const cartQuery = `SELECT * FROM cart WHERE brand='${opts.brand}' AND cab='${opts.cab}'`;
        const cartData = JSON.parse(await ambil_select('cart', cartQuery));
        
        return formatReportText(jualData, pesaniData, finalPosSettings, opts, cartData, registerData);
    } catch (err) {
        console.error("Gagal generate laporan:", err);
        return `Gagal membuat laporan: ${err.message}`;
    }
}

function formatReportText(jualData, pesaniData, posSettings, options, cartData, registerData) {
    const width = 42;
    let report = [];

    const centerText = (text) => text ? String(text).center(width) : '';
    const padRight = (text, len) => String(text).padEnd(len);
    const padLeft = (text, len) => String(text).padStart(len);
    const formatCurrency = (amount) => Math.round(Number(amount)).toLocaleString('id-ID');

    const menuItems = pesaniData.filter(p => String(p.sub || '0').trim() === '0' && (!p.payment || String(p.payment).trim() === ''));

    // --- HEADER BARU ---
    // Menggunakan data dari `posSettings` yang sudah digabungkan
    report.push(centerText(posSettings.nama || posSettings.nama_resto));
    report.push(centerText(posSettings.alamat || posSettings.alamat_resto));
    if (posSettings.ket) {
        report.push(centerText(posSettings.ket));
    }
    if (posSettings.kota) {
        report.push(centerText(posSettings.kota));
    }
    report.push('');
    // --- AKHIR HEADER BARU ---
    				report.push("".padStart(width, '='));
    				report.push("BUKTI TUTUP KASIR".center(width));
    				report.push("".padStart(width, '='));    
    if (options.registerNomor) {
        const kasirInfo = jualData.length > 0 ? jualData[0].user : (registerData ? registerData.user : options.kasir);
        report.push(`Kasir   : ${kasirInfo}`);
        report.push(`Register: ${options.registerNomor}`);
    } else {
        report.push(`Tanggal : ${options.startDate} s/d ${options.endDate}`);
        report.push(`Kasir   : ${options.kasir}`);
    }
    report.push('');

    // --- KALKULASI TOTAL ---
    const totalSales = jualData.reduce((sum, j) => sum + parseFloat(j.ttot || 0), 0);
    const totalItemDiscount = menuItems.reduce((sum, p) => sum + (Number(p.harga || 0) * Number(p.quantity || 1) * (Number(p.discp || 0) / 100)) + (Number(p.discr || 0) * Number(p.quantity || 1)), 0);
    const totalBillDiscount = pesaniData.filter(p => String(p.payment).trim() === '06').reduce((sum, p) => sum - Number(p.harga || 0), 0);
    const totalDiscount = totalItemDiscount + totalBillDiscount;
    const netSales = totalSales - totalDiscount;
    const totalService = jualData.reduce((sum, j) => sum + Number(j.tserv || 0), 0);
    const totalPajak = jualData.reduce((sum, j) => sum + Number(j.ttax || 0), 0);
    const totalRevenue = netSales + totalService + totalPajak;

    // --- BAGIAN TOTAL REVENUE ---
    report.push(`${padRight('TOTAL SALES', 15)}:${padLeft(jualData.length, 4)} ${padLeft(formatCurrency(totalSales), 21)}`);
    report.push(`${padRight('DISC ITEM', 15)}:${padLeft('', 4)} ${padLeft(formatCurrency(totalItemDiscount), 21)}`);
    report.push(`${padRight('DISC FAKTUR', 15)}:${padLeft('', 4)} ${padLeft(formatCurrency(totalBillDiscount), 21)}`);
    report.push(padLeft('--------------------', width));
    report.push(`${padRight('NET SALES', 15)}:${padLeft('', 4)} ${padLeft(formatCurrency(netSales), 21)}`);
    report.push(`${padRight('SERVICE', 15)}:${padLeft('', 4)} ${padLeft(formatCurrency(totalService), 21)}`);
    report.push(`${padRight('PAJAK REST', 15)}:${padLeft('', 4)} ${padLeft(formatCurrency(totalPajak), 21)}`);
    report.push(padLeft('--------------------', width));
    report.push(`${padRight('TOTAL REVENUE', 15)}:${padLeft('', 4)} ${padLeft(formatCurrency(totalRevenue), 21)}`);
    report.push('');
    
    // --- REKAPITULASI KASIR (untuk Tutup Register) ---


    // --- CASH COLLECTION ---
    report.push('CASH COLLECTION');
    const paymentMap = {};
    pesaniData.filter(p => p.payment && String(p.payment).trim() !== '06').forEach(p => {
        let method = (p.edc || p.name || 'UNKNOWN').toUpperCase();
        if (String(p.payment).trim() === '10') method = 'CASH';
        if (!paymentMap[method]) paymentMap[method] = { count: 0, amount: 0 };
        paymentMap[method].count++;
        paymentMap[method].amount += Number(p.harga || 0);
    });
    let totalPaymentAmount = 0;
    for (const method of Object.keys(paymentMap).sort()) {
        const data = paymentMap[method];
        if (data.amount > 0) {
            report.push(`${padRight(method, 18)} ${padLeft(data.count, 3)} ${padLeft(formatCurrency(data.amount), 19)}`);
            totalPaymentAmount += data.amount;
        }
    }
    report.push(padLeft('------------------', width));
    report.push(`${padRight('TOTAL PAYMENT', 26)} ${padLeft(formatCurrency(totalPaymentAmount), 15)}`);
    report.push('');

        if (options.registerNomor && registerData) {
        const allPaymentItems = pesaniData.filter(p => p.payment && String(p.payment).trim() !== '06');
        const totalPayment = allPaymentItems.reduce((sum, p) => sum + Number(p.harga), 0);
        const modalAwal = Number(registerData.saldoawal) || 0;
        const saldoAkhir = Number(options.saldoAkhir) || 0;
        const totalPenerimaanCash = allPaymentItems
            .filter(p => String(p.payment).trim() === '10')
            .reduce((sum, p) => sum + Number(p.harga), 0);

        const totalDiLaci = modalAwal + totalPenerimaanCash;
        const selisih = saldoAkhir - totalDiLaci;

        report.push(''.padStart(width, '='));
        report.push(centerText('REKAPITULASI KASIR'));
        report.push(''.padStart(width, '-'));
        report.push(padRight('MODAL AWAL', 20) + padLeft(formatCurrency(modalAwal), 22));
        report.push(padRight('TOTAL PENERIMAAN', 20) + padLeft(formatCurrency(totalPayment), 22));
        report.push(padRight('SALDO AKHIR (INPUT)', 20) + padLeft(formatCurrency(saldoAkhir), 22));
        report.push(padLeft('--------------------', width));
        report.push(padRight('SELISIH', 20) + padLeft(formatCurrency(selisih), 22));
        report.push(''.padStart(width, '='));
        report.push('');
    }
    // --- RINCIAN DISCOUNT ---
    report.push('RINCIAN DISCOUNT :');
    report.push('-'.repeat(width));
    const itemDiscountsByName = {};
    const discountedItems = menuItems.filter(p => p.dname && p.dname.trim() !== '');
    discountedItems.forEach(p => {
        const discName = `(I) ${p.dname.toUpperCase()}`;
        if (!itemDiscountsByName[discName]) itemDiscountsByName[discName] = { count: 0, amount: 0 };
        itemDiscountsByName[discName].count++;
        const itemDiscountAmount = (Number(p.harga || 0) * Number(p.quantity || 1) * (Number(p.discp || 0) / 100)) + (Number(p.discr || 0) * Number(p.quantity || 1));
        itemDiscountsByName[discName].amount += itemDiscountAmount;
    });

    for (const [name, data] of Object.entries(itemDiscountsByName)) {
        if (data.amount > 0) report.push(`${padRight(name, 20)} ${padLeft(data.count, 2)} ${padLeft(formatCurrency(data.amount), 18)}`);
    }

    const billDiscountsByName = {};
    const discountedBills = pesaniData.filter(p => String(p.payment).trim() === '06');
    discountedBills.forEach(p => {
        const discName = `(F) ${p.name.toUpperCase()}`;
        if (!billDiscountsByName[discName]) billDiscountsByName[discName] = { count: 0, amount: 0 };
        billDiscountsByName[discName].count++;
        billDiscountsByName[discName].amount += -Number(p.harga || 0);
    });
    
    for (const [name, data] of Object.entries(billDiscountsByName)) {
        if (data.amount > 0) report.push(`${padRight(name, 20)} ${padLeft(data.count, 2)} ${padLeft(formatCurrency(data.amount), 18)}`);
    }
    report.push(padLeft('------------------', width));
    report.push(`${padRight('Total Disc.', 26)} ${padLeft(formatCurrency(totalDiscount), 15)}`);
    report.push('');

    // --- SALES BY KATEGORI ---
    report.push('Sales By Kategory');
    report.push('-'.repeat(width));
    const catMap = {};
    menuItems.forEach(p => {
        const cat = (p.group_name || 'Uncategorized').toUpperCase();
        const itemTotal = Number(p.harga || 0) * Number(p.quantity || 1);
        if (!catMap[cat]) catMap[cat] = { qty: 0, amount: 0 };
        catMap[cat].qty += Number(p.quantity) || 1;
        catMap[cat].amount += itemTotal;
    });
    
    let totalCatQty = 0, totalCatAmount = 0;
    for (const [cat, data] of Object.entries(catMap).sort()) {
        totalCatQty += data.qty;
        totalCatAmount += data.amount;
        report.push(`${padRight(cat, 15)} ${padLeft(data.qty, 5)} ${padLeft(formatCurrency(data.amount), 20)}`);
    }
    report.push('-'.repeat(width));
    report.push(`${padRight('  Jumlah', 15)} ${padLeft(totalCatQty, 5)} ${padLeft(formatCurrency(totalCatAmount), 20)}`);
    report.push('');

    // --- AVERAGE ---
    const totalGuest = jualData.reduce((sum, j) => sum + (parseInt(j.cover) || 0), 0) || 1;
    report.push(`${padRight('Average Cover', 15)} ${padLeft(totalGuest, 5)} ${padLeft(formatCurrency(totalSales / totalGuest), 20)}`);
    report.push(`${padRight('Average Check', 15)} ${padLeft(jualData.length, 5)} ${padLeft(formatCurrency(totalSales / jualData.length), 20)}`);
    report.push('');

    return report.join('\n');
}

