// ================= VARIABLE INITIALIZATION =================
let chartRegistry = {};
let periods = [], revenueData = [], expenseData = [];
let product = [], revByProduct = [];
let clientsAcquiredByProduct = [], clientsAcquiredByPeriod = [];
let productGroups = [], revenueByProductGroup = [];
let catPeriodData = [], expTypeData = [], licenseData = [], revTypeData = [], topProjects = [];
let groupLevel = 'fy';
let checker = false;

let fyFilter = '', quarterFilter = '', monthFilter = '';
let categoryFilter = '', licenseFilter = '', paymentType = '';

const chartIds = [
    'revenueByPeriod', 'revenueVsExpense',
    'revenueByCategory', 'clientsByCategory', 'revenueBySubCat',
    'categoryByPeriod', 'expenseByType', 'clientsByPeriod',
    'licenseByPeriod', 'revTypeByPeriod', 'topProjects'
];

// ================= GRADIENT MAKER =================
function gradientMaker(count, startColor, endColor) {
    if (count === 1) return ['rgb(229, 84, 81)'];
    const colors = [];
    for (let i = 0; i < count; i++) {
        const r = Math.round(startColor[0] + (endColor[0] - startColor[0]) * (i / (count - 1)));
        const g = Math.round(startColor[1] + (endColor[1] - startColor[1]) * (i / (count - 1)));
        const b = Math.round(startColor[2] + (endColor[2] - startColor[2]) * (i / (count - 1)));
        colors.push(`rgb(${r}, ${g}, ${b})`);
    }
    return colors;
}

// ================= SERIES COLORS =================
const SERIES_COLORS = [
    'rgba(255,99,132,0.7)', 'rgba(54,162,235,0.7)', 'rgba(255,206,86,0.7)',
    'rgba(75,192,192,0.7)', 'rgba(153,102,255,0.7)', 'rgba(255,159,64,0.7)',
    'rgba(99,255,132,0.7)', 'rgba(235,54,162,0.7)'
];

// ================= FORMAT INR =================
function formatINR(value) {
    const num = Number(value);
    if (isNaN(num)) return value;
    if (Math.abs(num) >= 10000000) return (num / 10000000).toFixed(2) + ' Cr';
    if (Math.abs(num) >= 100000)   return (num / 100000).toFixed(2) + ' L';
    if (Math.abs(num) >= 1000)     return (num / 1000).toFixed(2) + 'K';
    return num.toLocaleString('en-IN');
}

// ================= SHIMMER =================
function showShimmer() {
    chartIds.forEach(id => {
        const c = document.getElementById(id);
        if (!c) return;
        const p = c.parentElement;
        let l = p.querySelector('.chart-loader');
        if (!l) { l = document.createElement('div'); l.className = 'chart-loader'; p.appendChild(l); }
        l.style.display = 'block';
    });
}

function hideShimmer() {
    chartIds.forEach(id => {
        const c = document.getElementById(id);
        if (!c) return;
        const l = c.parentElement.querySelector('.chart-loader');
        if (l) l.style.display = 'none';
    });
}

function updateData() { showShimmer(); getData(); }

async function dataUpdated() {
    chartIds.forEach(id => buildChart(id));
    await new Promise(r => setTimeout(r, 800));
    hideShimmer();
}

// ================= GET DATA =================
function getData() {
    if (checker) {
        fyFilter       = document.getElementById('fyFilter')?.value          ?? '';
        quarterFilter  = document.getElementById('quarterFilter')?.value     ?? '';
        monthFilter    = document.getElementById('monthFilter')?.value       ?? '';
        categoryFilter = document.getElementById('categoryFilter')?.value    ?? '';
        licenseFilter  = document.getElementById('licenseFilter')?.value     ?? '';
        paymentType    = document.getElementById('revenueTypeFilter')?.value ?? '';
    }

    fetch('main.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({
            fyFilter, quarterFilter, monthFilter,
            categoryFilter, licenseFilter,
            paymentMethod: paymentType,
            checker: checker ? '1' : '0'
        })
    })
    .then(res => res.json())
    .then(data => {
        if (!data || typeof data !== 'object' || data.error) {
            console.error('API error:', data?.error ?? data);
            hideShimmer();
            return;
        }

        periods                  = Array.isArray(data.periods)                  ? data.periods                              : [];
        revenueData              = Array.isArray(data.revenue)                  ? data.revenue.map(Number)                  : [];
        expenseData              = Array.isArray(data.expenseData)              ? data.expenseData.map(Number)              : [];
        product                  = Array.isArray(data.product)                  ? data.product                              : [];
        revByProduct             = Array.isArray(data.revByProduct)             ? data.revByProduct.map(Number)             : [];
        clientsAcquiredByProduct = Array.isArray(data.clientsAcquiredByProduct) ? data.clientsAcquiredByProduct.map(Number) : [];
        clientsAcquiredByPeriod  = Array.isArray(data.clientsAcquiredByPeriod)  ? data.clientsAcquiredByPeriod.map(Number)  : [];
        productGroups            = Array.isArray(data.productGroups)            ? data.productGroups                        : [];
        revenueByProductGroup    = Array.isArray(data.revenueByProductGroup)    ? data.revenueByProductGroup.map(Number)    : [];
        catPeriodData            = Array.isArray(data.catPeriodData)            ? data.catPeriodData                        : [];
        expTypeData              = Array.isArray(data.expTypeData)              ? data.expTypeData                          : [];
        licenseData              = Array.isArray(data.licenseData)              ? data.licenseData                          : [];
        revTypeData              = Array.isArray(data.revTypeData)              ? data.revTypeData                          : [];
        topProjects              = Array.isArray(data.topProjects)              ? data.topProjects                          : [];
        groupLevel               = data.groupLevel ?? 'fy';

        if (!checker) {
            checker = true;

            const fyEl = document.getElementById('fyFilter');
            if (fyEl && Array.isArray(data.fyList)) {
                fyEl.innerHTML = '<option value="">All Years</option>';
                data.fyList.forEach(fy => {
                    const opt = document.createElement('option');
                    opt.value       = fy.FY_Code;
                    opt.textContent = 'FY ' + fy.FY_Short;
                    fyEl.appendChild(opt);
                });
            }
            populateSelect('quarterFilter',     data.quarterList,     'All Quarters');
            populateSelect('monthFilter',       data.monthList,       'All Months');
            populateSelect('categoryFilter',    data.categoryList,    'All Categories');
            populateSelect('licenseFilter',     data.licenseList,     'All License Types');
            populateSelect('revenueTypeFilter', data.revenueTypeList, 'All Revenue Types');
        }
// ── Filtered totals for charts ──
const totalRev  = revenueData.reduce((a, b) => a + b, 0);
const totalExp  = expenseData.reduce((a, b) => a + b, 0);
const netProfit = totalRev - totalExp;
const margin    = totalRev > 0 ? ((netProfit / totalRev) * 100).toFixed(1) : '0.0';

// ── KPI cards: current-FY when no filter, else filtered totals ──
const hasFilter = fyFilter || quarterFilter || monthFilter || categoryFilter || licenseFilter || paymentType;

const kpiRev    = hasFilter ? totalRev    : (data.kpiCurrentFY?.totalRevenue  ?? totalRev);
const kpiExp    = hasFilter ? totalExp    : (data.kpiCurrentFY?.totalExpenses ?? totalExp);
const kpiNet    = hasFilter ? netProfit   : (data.kpiCurrentFY?.netProfit     ?? netProfit);
const kpiMgn    = hasFilter ? margin      : ((data.kpiCurrentFY?.profitMargin ?? parseFloat(margin)).toFixed(1));

document.getElementById('kpiRevenue').textContent  = '₹ ' + formatINR(kpiRev);
document.getElementById('kpiExpense').textContent  = '₹ ' + formatINR(kpiExp);
document.getElementById('kpiProfit').textContent   = '₹ ' + formatINR(Math.abs(kpiNet));
document.getElementById('kpiMargin').textContent   = kpiMgn + '%';
document.getElementById('profitLabel').textContent = kpiNet >= 0 ? 'Net Profit' : 'Net Loss';
        dataUpdated();
    })
    .catch(err => { console.error('Fetch error:', err); hideShimmer(); });
}

// ================= POPULATE SELECT =================
function populateSelect(id, values, placeholder) {
    const sel = document.getElementById(id);
    if (!sel || !Array.isArray(values)) return;
    sel.innerHTML = `<option value="">${placeholder}</option>`;
    values.forEach(v => {
        const opt = document.createElement('option');
        opt.value = v; opt.textContent = v;
        sel.appendChild(opt);
    });
}

// ================= REMOVE CHART =================
function removeChart(id) {
    if (chartRegistry[id]) { chartRegistry[id].destroy(); delete chartRegistry[id]; }
}

// ================= BASE OPTIONS =================
// KEY RULES:
// 1. Category axis  → type:'category', NO beginAtZero, NO custom callback
//    (beginAtZero on a category axis makes Chart.js treat labels as 0,1,2 indices)
// 2. Value axis     → type:'linear', beginAtZero:true, formatINR callback
// When indexAxis='x': X=category, Y=value (vertical bars — default)
// When indexAxis='y': Y=category, X=value (horizontal bars)
function baseOpts(indexAxis = 'x') {
    const categoryAxis = {
        type: 'category',
        ticks: { color: 'white' },
        grid:  { color: 'rgba(255,255,255,0.06)' }
    };

    const valueAxis = {
        type: 'linear',
        beginAtZero: true,
        ticks: {
            color: 'white',
            callback: v => formatINR(Number(v))
        },
        grid: { color: 'rgba(255,255,255,0.06)' }
    };

    return {
        responsive: true,
        maintainAspectRatio: false,
        indexAxis,
        plugins: {
            legend: { display: false, labels: { color: 'white' } },
            datalabels: { display: false }
        },
        scales: {
            x: indexAxis === 'y' ? valueAxis   : categoryAxis,
            y: indexAxis === 'x' ? valueAxis   : categoryAxis
        }
    };
}

// ================= MULTI-SERIES OPTIONS =================
function multiOpts(indexAxis = 'x') {
    const o = baseOpts(indexAxis);
    o.plugins.legend = {
        display: true,
        position: 'top',
        labels: { color: 'white', boxWidth: 12, font: { size: 11 } }
    };
    return o;
}

// ================= DATALABELS HELPER =================
// FIX: Values were only visible on hover because baseOpts sets datalabels display:false.
// withDatalabels() wraps any opts object and enables visible datalabels.
// isINR=true  → shows ₹ prefix with formatINR formatting
// isINR=false → shows raw integer (for client counts etc.)
function withDatalabels(opts, isINR = true) {
    return {
        ...opts,
        plugins: {
            ...opts.plugins,
            datalabels: {
                display: true,
                color: 'white',
                font: { weight: 'bold', size: 10 },
                anchor: 'end',
                align: 'end',
                clip: false,
                formatter: v => isINR ? '₹' + formatINR(v) : String(v)
            }
        }
    };
}

// ================= BUILD MULTI SERIES =================
// PHP sends all keys lowercase via array_change_key_case — read lowercase keys only.
function buildMultiSeries(rows, groupKey, valueKey, colors) {
    const gk = groupKey.toLowerCase();
    const vk  = valueKey.toLowerCase();
    const seriesMap = {};
    rows.forEach(r => {
        const sk = r[gk];
        if (!seriesMap[sk]) seriesMap[sk] = {};
        seriesMap[sk][r.periodname] = parseFloat(r[vk]) || 0;
    });
    return Object.keys(seriesMap).map((sk, i) => ({
        label: sk,
        data: periods.map(p => seriesMap[sk][p] ?? 0),
        backgroundColor: (colors || SERIES_COLORS)[i % (colors || SERIES_COLORS).length],
        borderRadius: 3
    }));
}

// ================= BUILD CHART =================
function buildChart(id) {
    const ctx = document.getElementById(id);
    if (!ctx) return;
    removeChart(id);

    switch (id) {

        // ── Revenue by Period ──────────────────────────────────────────
        case 'revenueByPeriod': {
            const colors = gradientMaker(periods.length, [175, 220, 236], [0, 0, 255]);
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: periods,
                    datasets: [{
                        label: 'Revenue',
                        data: revenueData,
                        backgroundColor: colors,
                        borderRadius: 4
                    }]
                },
                options: withDatalabels(baseOpts('x'), true)
            });
            break;
        }

        // ── Revenue vs Expense ─────────────────────────────────────────
        case 'revenueVsExpense': {
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: periods,
                    datasets: [
                        { label: 'Revenue', data: revenueData, backgroundColor: 'rgba(75,192,130,0.75)', borderRadius: 3 },
                        { label: 'Expense', data: expenseData, backgroundColor: 'rgba(229,84,81,0.75)',  borderRadius: 3 }
                    ]
                },
                // Multi-series: skip per-bar datalabels to avoid clutter; legend visible
                options: multiOpts('x')
            });
            break;
        }

        // ── Revenue by Category (horizontal bar) ───────────────────────
        case 'revenueByCategory': {
            const colors = gradientMaker(product.length, [84, 197, 113], [4, 99, 7]);
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: product,
                    datasets: [{
                        label: 'Revenue',
                        data: revByProduct,
                        backgroundColor: colors,
                        borderRadius: 3
                    }]
                },
                options: withDatalabels(baseOpts('y'), true)
            });
            break;
        }

        // ── Clients by Category ────────────────────────────────────────
        case 'clientsByCategory': {
            const colors = gradientMaker(product.length, [238, 232, 170], [255, 165, 0]);
            // Y (value) axis should show plain integers, not INR
            const o = withDatalabels(baseOpts('x'), false);
            o.scales.y.ticks.callback = v => v;
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: product,
                    datasets: [{
                        label: 'Clients',
                        data: clientsAcquiredByProduct,
                        backgroundColor: colors,
                        borderRadius: 3
                    }]
                },
                options: o
            });
            break;
        }

        // ── Revenue by Sub Category (Pie) ──────────────────────────────
        case 'revenueBySubCat': {
            chartRegistry[id] = new Chart(ctx, {
                type: 'pie',
                data: {
                    labels: productGroups,
                    datasets: [{
                        data: revenueByProductGroup,
                        backgroundColor: ['#4bc0c0','#ff6384','#36a2eb','#ffce56','#a028ff','#ff8042','#4caf50']
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            display: true,
                            position: 'right',
                            labels: { color: 'white', font: { size: 11 }, boxWidth: 12 }
                        },
                        // Show percentage labels on pie slices
                        datalabels: {
                            display: true,
                            color: 'white',
                            font: { weight: 'bold', size: 11 },
                            formatter: (value, ctx) => {
                                const total = ctx.dataset.data.reduce((a, b) => a + b, 0);
                                return total > 0 ? ((value / total) * 100).toFixed(1) + '%' : '';
                            }
                        }
                    }
                }
            });
            break;
        }

        // ── Category Revenue by Period ─────────────────────────────────
        case 'categoryByPeriod': {
            const datasets = buildMultiSeries(catPeriodData, 'productName', 'totalRevenue', SERIES_COLORS);
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: { labels: periods, datasets },
                options: multiOpts('x')
            });
            break;
        }

        // ── Expense by Type ────────────────────────────────────────────
        case 'expenseByType': {
            const expColors = [
                'rgba(229,84,81,0.7)', 'rgba(255,206,86,0.7)', 'rgba(255,159,64,0.7)',
                'rgba(153,102,255,0.7)', 'rgba(54,162,235,0.7)', 'rgba(75,192,192,0.7)',
                'rgba(235,54,162,0.7)'
            ];
            const datasets = buildMultiSeries(expTypeData, 'expType', 'totalExpenses', expColors);
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: { labels: periods, datasets },
                options: multiOpts('x')
            });
            break;
        }

        // ── Clients by Period (horizontal bar) ─────────────────────────
        case 'clientsByPeriod': {
            const colors = gradientMaker(periods.length, [0, 200, 225], [0, 0, 225]);
            // X (value) axis should show plain integers, not INR
            const o = withDatalabels(baseOpts('y'), false);
            o.scales.x.ticks.callback = v => v;
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: periods,
                    datasets: [{
                        label: 'Clients',
                        data: clientsAcquiredByPeriod,
                        backgroundColor: colors,
                        borderRadius: 3
                    }]
                },
                options: o
            });
            break;
        }

        // ── License by Period ──────────────────────────────────────────
        case 'licenseByPeriod': {
            const datasets = buildMultiSeries(licenseData, 'licType', 'totalRevenue', SERIES_COLORS);
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: { labels: periods, datasets },
                options: multiOpts('x')
            });
            break;
        }

        // ── Revenue Type by Period ─────────────────────────────────────
        case 'revTypeByPeriod': {
            const datasets = buildMultiSeries(revTypeData, 'revType', 'totalRevenue', [
                'rgba(54,162,235,0.75)', 'rgba(255,99,132,0.75)'
            ]);
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: { labels: periods, datasets },
                options: multiOpts('x')
            });
            break;
        }

        // ── Top 5 Projects (horizontal bar) ───────────────────────────
        case 'topProjects': {
            // FIX: PHP returns lowercase keys — use r.projectname, r.totalrevenue
            const names  = topProjects.map(r => r.projectname);
            const vals   = topProjects.map(r => parseFloat(r.totalrevenue));
            const colors = gradientMaker(names.length, [202, 34, 107], [255, 51, 170]);
            chartRegistry[id] = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: names,
                    datasets: [{
                        label: 'Revenue',
                        data: vals,
                        backgroundColor: colors,
                        borderRadius: 3
                    }]
                },
                options: withDatalabels(baseOpts('y'), true)
            });
            break;
        }
    }
}

function toggleCollapse(el) { el.classList.toggle('active'); }