// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Report charts module.
 *
 * @module     aiprovider_datacurso/report_charts
 * @copyright  2025 Industria Elearning
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

import Ajax from 'core/ajax';
import Chart from 'core/chartjs';
import { get_string as getString } from 'core/str';
import Notification from 'core/notification';
import AutoComplete from 'core/form-autocomplete';

export const init = async () => {

    const date = await getString('date', 'core');
    const creditsConsumedMonth = await getString('tokensconsumedmonth', 'aiprovider_datacurso');
    const creditsConsumedDay = await getString('tokensconsumedday', 'aiprovider_datacurso');
    const creditsConsumed = await getString('tokensconsumed', 'aiprovider_datacurso');

    const tokensAvailable = document.getElementById('tokens-available');
    const tokensConsumed = document.getElementById('tokens-consumed');
    const userTokensConsumed = document.getElementById('user-tokens-consumed');

    let chartBar, chartPie, chartDay, chartUser;
    let cachedData = [];

    Promise.all([
        Ajax.call([{ methodname: 'aiprovider_datacurso_get_credits_balance', args: {} }])[0],
        Ajax.call([{ methodname: 'aiprovider_datacurso_get_services', args: {} }])[0],
        Ajax.call([{ methodname: 'aiprovider_datacurso_get_all_consumption', args: {} }])[0],
    ])
        .then(([balanceResponse, servicesResponse, consumptionResponse]) => {
            const balance = balanceResponse?.balance || 0;
            tokensAvailable.textContent = balance;
            const services = servicesResponse?.services || [];
            cachedData = consumptionResponse?.consumption || [];
            initCharts(services);
        })
        .catch((e) => {
            let msg = e.message;
            Notification.addNotification({
                message: msg,
                type: 'error'
            });
        });

    // Init graphs.
    const initCharts = async (services) => {
        const filterBar = document.getElementById('filter-service-bar');
        const filterPie = document.getElementById('filter-service-pie');
        const filterUser = document.getElementById('filter-user-charts');
        const filterStart = document.getElementById('filter-start-date');
        const filterEnd = document.getElementById('filter-end-date');

        const fillSelect = (select, items) => {
            if (items?.length) {
                items.forEach(item => {
                    const opt = document.createElement('option');
                    opt.value = item.id;
                    opt.textContent = item.name || item.fullname;
                    select.appendChild(opt);
                });
            }
        };

        fillSelect(filterBar, services);
        fillSelect(filterPie, services);

        // Enhance with Autocomplete for User Chart (AJAX)
        const placeholder = await getString('search', 'core');
        AutoComplete.enhance(
            '#filter-user-charts',
            false,
            'aiprovider_datacurso/repository',
            placeholder,
            false,
            true,
            '',
            false,
            1
        );

        // Render init used cachedData for others, but specific user data for UserChart
        renderBarChart(cachedData);
        renderPieChart(cachedData);
        renderDayChart(cachedData);

        if (filterUser.value) {
            updateUserChart();
        } else {
            renderUserChart([]); // Empty chart if no user
        }

        // Listeners filters
        filterBar.addEventListener('change', () => updateBarChart());
        filterPie.addEventListener('change', () => updatePieChart());
        filterUser.addEventListener('change', () => updateUserChart());
        filterStart.addEventListener('change', () => updateDayChart());
        filterEnd.addEventListener('change', () => updateDayChart());
    };

    // functions ws
    const fetchConsumptionData = async (params = {}) => {
        const defaults = {
            service: "",
            action: "",
            userid: 0,
            fromdate: "",
            todate: ""
        };
        const finalParams = { ...defaults, ...params };

        try {
            const response = await Ajax.call([{
                methodname: 'aiprovider_datacurso_get_all_consumption',
                args: finalParams
            }])[0];

            if (response.status !== 'success') {
                return [];
            }
            return response.consumption || [];

        } catch (error) {
            Notification.exception(error);
            return [];
        }
    };

    // grafic bar
    const renderBarChart = (data) => {
        const byMonth = {};
        data.forEach(c => {
            const month = c.date.substring(0, 7);
            byMonth[month] = (byMonth[month] || 0) + c.cant_tokens;
        });

        const totalTokens = data.reduce((sum, c) => sum + (c.cant_tokens || 0), 0);
        tokensConsumed.textContent = totalTokens;

        const ctx = document.getElementById('chart-tokens-by-month');
        if (chartBar) {
            chartBar.destroy();
        }

        chartBar = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: Object.keys(byMonth),
                datasets: [{
                    label: creditsConsumedMonth,
                    data: Object.values(byMonth),
                    backgroundColor: '#0073e6',
                }]
            },
            options: { responsive: true, maintainAspectRatio: false }
        });
    };

    const updateBarChart = async () => {
        const service = document.getElementById('filter-service-bar').value;
        if (!service) {
            return renderBarChart(cachedData);
        }
        const data = await fetchConsumptionData({ service });
        renderBarChart(data);
    };

    // grafic pie
    const renderPieChart = (data) => {
        const byAction = {};
        data.forEach(c => {
            byAction[c.action] = (byAction[c.action] || 0) + c.cant_tokens;
        });

        const ctx = document.getElementById('chart-actions');
        if (chartPie) {
            chartPie.destroy();
        }

        chartPie = new Chart(ctx, {
            type: 'pie',
            data: {
                labels: Object.keys(byAction),
                datasets: [{
                    data: Object.values(byAction),
                    backgroundColor: [
                        '#36A2EB',
                        '#FF6384',
                        '#f1d48bff',
                        '#5ddcdcff',
                        '#049930ff',
                        '#0b6eb0ff',
                        '#d10f39ff',
                        '#7c611dff',
                        '#ee9610ff',
                        '#a50562ff',
                        '#022082ff',
                        '#efef21ff',
                        '#3f4646ff',
                        '#8f9191ff',
                        '#0c361bff',
                        '#bd836cff'
                    ],
                }]
            },
            options: { responsive: true, maintainAspectRatio: false }
        });
    };

    const updatePieChart = async () => {
        const service = document.getElementById('filter-service-pie').value;
        if (!service) {
            return renderPieChart(cachedData);
        }

        const data = await fetchConsumptionData({ service });
        renderPieChart(data);
    };

    // grafic day
    const renderDayChart = (data) => {
        const byDay = {};
        data.forEach(c => {
            const day = c.date.substring(0, 10);
            byDay[day] = (byDay[day] || 0) + c.cant_tokens;
        });

        const labels = Object.keys(byDay).sort((a, b) => new Date(a) - new Date(b));
        const values = labels.map(day => byDay[day]);

        const ctx = document.getElementById('chart-tokens-by-day');
        if (chartDay) {
            chartDay.destroy();
        }

        chartDay = new Chart(ctx, {
            type: 'line',
            data: {
                labels,
                datasets: [{
                    label: creditsConsumedDay,
                    data: values,
                    borderColor: '#28a745',
                    backgroundColor: 'rgba(40,167,69,0.2)',
                    fill: true,
                    tension: 0.2,
                    pointRadius: 4,
                    pointHoverRadius: 6,
                    borderWidth: 2
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    x: { title: { display: true, text: date } },
                    y: { title: { display: true, text: creditsConsumed }, beginAtZero: true }
                }
            }
        });
    };

    const updateDayChart = async () => {
        const fromdate = document.getElementById('filter-start-date').value;
        const todate = document.getElementById('filter-end-date').value;

        if (!fromdate && !todate) {
            return renderDayChart(cachedData);
        }

        const data = await fetchConsumptionData({ fromdate, todate });
        renderDayChart(data);
    };

    // grafic user per service
    const renderUserChart = (data) => {
        const byService = {};
        let total = 0;

        // Group by service ID and sum tokens
        data.forEach(c => {
            const serviceName = c.service || c.id_service;
            byService[serviceName] = (byService[serviceName] || 0) + (c.cant_tokens || 0);
            total += (c.cant_tokens || 0);
        });

        if (userTokensConsumed) {
            userTokensConsumed.textContent = total.toFixed(2);
        }

        const ctx = document.getElementById('chart-user-consumption');
        if (!ctx) {
            return;
        }

        if (chartUser) {
            chartUser.destroy();
        }

        chartUser = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: Object.keys(byService),
                datasets: [{
                    label: creditsConsumed,
                    data: Object.values(byService),
                    backgroundColor: '#6c757d',
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                indexAxis: 'y',
            }
        });
    };

    const updateUserChart = async () => {
        const userId = document.getElementById('filter-user-charts').value;
        if (!userId) {
            return renderUserChart(cachedData);
        }

        const data = await fetchConsumptionData({ userid: userId });
        renderUserChart(data);
    };
};
