// VARIABLE INITIALIZATION TO AVOID ERRORS ON FIRST LOADING
let {
    chartRegistry = [],
    total_revenue = 0,
    total_orders = 0,
    avg_order_value = 0,
    delivery_rate = 0,
    delivered_orders = 0,
    paid_orders = 0,
    courier_partners = [],
    average_delivery_days = [],
    top_cities = [],
    top_revenue = [],
    genders = [],
    order_count_by_gender = [],
    payment_methods = [],
    revenue_by_payment = [],
    order_status = [],
    order_count = [],
    categories = [],
    revenue_by_categories = [],
    wholeData = {}
} = {};

function animateValue(elementId, start, end, duration, formatter = (val) => val) {
    const element = document.getElementById(elementId);
    const range = end - start;
    const stepTime = 16;
    const steps = Math.ceil(duration / stepTime);
    let currentStep = 0;

    const timer = setInterval(() => {
        currentStep++;
        const progress = currentStep / steps;
        const value = start + range * progress;
        element.innerHTML = formatter(value);

        if (currentStep >= steps) {
            clearInterval(timer);
            element.innerHTML = formatter(end);
        }
    }, stepTime);
}

const inrFormatter = new Intl.NumberFormat("en-IN", {
    style: "currency",
    currency: "INR",
    maximumFractionDigits: 0
});

const numberFormatter = new Intl.NumberFormat("en-IN");

// MAIN FUNCTION RESPONSIBLE FOR FETCHING DATA USING API HIT
function getData() {

    // GATHERING FILTERS TO SEND IN API FOR GAINING FILTERED DATA
    // CHECKER TO AVOID FIRST TIME LOADING ERRORS
    // WHEN FIRST API IS HIT THE FILTERS ARE NOT ESTABLISHED SO CHECKER STORES IF FILTERS HAVE DATA
    // IF CHECKER IS TRUE => FIRST API HIT SUCCESSFULLY
    // IF CHECKER IS FALSE => FIRST API HIT IS NOT SUCCESSFUL OR UNDERGOING EXECUTION


    // CUSTOM MADE API ACCESSED BY PHP
    fetch('salesAnalyticsFetch.php', {

        // POST METHOD
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    })
        // RETURNING RESPONSE TO ACCESS THE DATA FROM THE SERVER INTO THE SCRIPT
        .then(response => response.json())
        // USING DATA TO BIND THEM WITH FRONT END ELEMENTS
        .then(data => {
            wholeData = data;
            total_revenue = data.kpi.total_revenue;
            total_orders = data.kpi.total_orders;
            avg_order_value = data.kpi.avg_order_value;
            delivery_rate = (data.kpi.delivered_orders * 100) / data.kpi.total_orders;
            delivered_orders = data.kpi.delivered_orders;
            paid_orders = data.kpi.paid_orders;

            courier_partners = data.courier_avg_days.map(item => item["Courier Partner"]);
            average_delivery_days = data.courier_avg_days.map(item => parseFloat(item.avg_days).toFixed(2));

            top_cities = data.top_cities.map(item => item.City);
            top_revenue = data.top_cities.map(item => parseFloat(item.total_revenue).toFixed(0));

            genders = data.gender.map(item => {
                if (item.Gender === "M") return "Male";
                if (item.Gender === "F") return "Female";
                return item.Gender;
            });
            order_count_by_gender = data.gender.map(item => parseInt(item.count));

            payment_methods = data.payment_methods.map(item => item["Payment Method"]);
            revenue_by_payment = data.payment_methods.map(item => parseFloat(item.total_revenue).toFixed(0));

            order_status = data.order_status.map(item => item["Order Status"]);
            order_count = data.order_status.map(item => parseInt(item.count));

            categories = data.categories.map(item => item.ProdCategory);
            revenue_by_categories = data.categories.map(item => parseFloat(item.total_revenue).toFixed(0));


            // Apply values to DOM
            animateValue('totalRevenueKpi', 0, total_revenue, 1000, (val) => inrFormatter.format(val));
            animateValue('totalOrdersKpi', 0, total_orders, 1000, (val) => numberFormatter.format(val));
            animateValue('avgOrderValueKpi', 0, avg_order_value, 1000, (val) => inrFormatter.format(val));
            animateValue('deliveryRateKpi', 0, delivery_rate, 1000, (val) => val.toFixed(2) + " %");
            animateValue('paidOrdersKpi', 0, paid_orders, 1000, (val) => numberFormatter.format(val));
            animateValue('deliveredOrdersKpi', 0, delivered_orders, 1000, (val) => numberFormatter.format(val));
            chartIds.forEach(initChart);
            document.getElementById('preloader').classList.add('fade-out');
        })

        // RETURNING TO THE FRONTEND IF ENCOUNTERED DURING API CALLING OR HIT
        .catch(error => {
            console.error('Error:', error);
        });
    return;
}

// LIST STORING ALL THE IDS OF CHARTS
const chartIds = [
    "revenueByCategory",
    "ordersByStatus",
    "revenueByPayment",
    "ordersByGender",
    "topCitiesRevenue",
    "averageDeliveryDays"
];


// FUNTION TO CALL ON CLICK BY UPDATE BUTTON AND FILTER CHANGES
function updateData() {

    // MAKING PRELOADER APPEAR WHEN DATA IS REQUESTED TO BE CHANGED BY THE USER

    document.getElementById('preloader').classList.remove('fade-out');

    // CALLING MAIN FUNCTION TO HIT API AGAIN AND UPDATE THE NEW DATA

    getData();
}


function dataUpdated() {
    // INITIALIZING ALL THE CHARTS AGAIN
    // initChart FUNCTION FIRST REMOVES ALL THE CHARTS AND CREATE THE CHARTS AGAIN SO THAT NEW VALUES DISPLAY INSTANTLY
    chartIds.forEach(initChart);

    // REMOVING WORKTYPE AND FINANCIALYEAR ID FROM FOCUS TO STOP FOCUS ANIMATIONS BY CSS
    document.getElementById('workType').blur();
    document.getElementById('financialYear').blur();

}

getData();