import { formatDateTime } from '../../common/common.js';
import dashBoardService from '../../apis/dashboard-api.js';

let selectedMonth;

document.addEventListener('DOMContentLoaded', () => {
    initMonthPicker();
    fetchDataAndRender();
});

const initMonthPicker = () => {
    const monthPicker = document.getElementById('monthPicker');
    selectedMonth = dayjs().format('YYYY-MM');
    monthPicker.value = selectedMonth;

    monthPicker.addEventListener('click', (event) => {
        event.preventDefault();
        monthPicker.showPicker();
    });

    monthPicker.addEventListener('change', ({ target: { value } }) => {
        selectedMonth = value;
        if (selectedMonth) fetchDataAndRender();
    });
};

const fetchDataAndRender = async () => {
    const [year, month] = selectedMonth.split('-');
    const [batchData, recentJobs] = await Promise.all([
        dashBoardService.getBatchJobExecutionData(year, month),
        dashBoardService.getRecentJobs()
    ]);

    renderBatchExecutionTimeChart(batchData.jobAvgSummary);
    renderBatchStatusChart(batchData.statusCounts);
    renderHourlyJobExecutionChart(batchData.jobHourSummary);
    renderDailyJobExecutionsChart(batchData.jobExecutionSummary);
    renderRecentJobsTable(recentJobs);
};

const chartOptions = {
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
        legend: { position: 'top' },
        title: { font: { size: 16 } }
    }
};

let batchExecutionTimeChart;
const renderBatchExecutionTimeChart = (data) => {
    if (batchExecutionTimeChart) batchExecutionTimeChart.destroy();

    const jobExecutionTimes = data.reduce((acc, job) => {
        if (job.endTime && job.startTime) {
            const duration = (new Date(job.endTime) - new Date(job.startTime)) / 1000;
            if (!acc[job.jobName]) acc[job.jobName] = { total: 0, count: 0 };
            acc[job.jobName].total += duration;
            acc[job.jobName].count++;
        }
        return acc;
    }, {});

    const averageExecutionTimes = Object.fromEntries(
        Object.entries(jobExecutionTimes).map(([jobName, { total, count }]) => [jobName, total / count])
    );

    const ctx = document.getElementById('batchExecutionTimeChart').getContext('2d');
    batchExecutionTimeChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: Object.keys(averageExecutionTimes),
            datasets: [{
                label: '평균 실행 시간 (초)',
                data: Object.values(averageExecutionTimes),
                backgroundColor: 'rgba(54, 162, 235, 0.6)',
                borderColor: 'rgba(54, 162, 235, 3)',
                borderWidth: 3
            }]
        },
        options: {
            ...chartOptions,
            plugins: {
                ...chartOptions.plugins,
                tooltip: {
                    callbacks: {
                        label: (context) => `${context.dataset.label || ''}: ${context.parsed.y.toFixed(2)} 초`
                    }
                }
            },
            scales: {
                y: {
                    beginAtZero: true,
                    title: { display: true, text: '시간 (초)' }
                }
            }
        }
    });
};

let batchStatusChart;
const renderBatchStatusChart = (data) => {
    if (batchStatusChart) batchStatusChart.destroy();

    const statusTotals = data.reduce((acc, { status, count }) => {
        acc[status] = (acc[status] || 0) + count;
        return acc;
    }, {});

    const statusColors = {
        'COMPLETED': 'rgba(75, 192, 192, 0.6)',
        'FAILED': 'rgba(255, 99, 132, 0.6)',
        'STARTING': 'rgba(255, 206, 86, 0.6)',
        'STARTED': 'rgba(54, 162, 235, 0.6)',
        'STOPPING': 'rgba(153, 102, 255, 0.6)',
        'STOPPED': 'rgba(255, 159, 64, 0.6)',
        'ABANDONED': 'rgba(201, 203, 207, 0.6)'
    };

    const ctx = document.getElementById('batchStatusChart').getContext('2d');
    batchStatusChart = new Chart(ctx, {
        type: 'pie',
        data: {
            labels: Object.keys(statusTotals),
            datasets: [{
                data: Object.values(statusTotals),
                backgroundColor: Object.values(statusColors)
            }]
        },
        options: {
            ...chartOptions,
            plugins: {
                ...chartOptions.plugins,
                tooltip: {
                    callbacks: {
                        title: () => null,
                        label: ({ label, parsed }) => `${label}: ${parsed}`,
                        afterLabel: ({ label }) => data
                            .filter(item => item.status === label)
                            .map(item => `  ${item.jobName}: ${item.count}`)
                            .join('\n')
                    }
                }
            }
        }
    });
};

let hourlyJobExecutionChart;
const renderHourlyJobExecutionChart = (data) => {
    if (hourlyJobExecutionChart) hourlyJobExecutionChart.destroy();

    const ctx = document.getElementById('hourlyJobExecutionChart').getContext('2d');
    const hours = Array.from({ length: 24 }, (_, i) => i);
    const jobNames = [...new Set(data.map(item => item.jobName))];

    const datasets = jobNames.map(jobName => ({
        label: jobName,
        data: hours.map(hour => data.find(item => item.jobName === jobName && item.hour === hour)?.count || 0),
        borderColor: getRandomColor(),
        backgroundColor: 'rgba(0, 0, 0, 0.1)',
        fill: false
    }));

    hourlyJobExecutionChart = new Chart(ctx, {
        type: 'line',
        data: { labels: hours.map(hour => `${hour}:00`), datasets },
        options: {
            ...chartOptions,
            plugins: {
                ...chartOptions.plugins,
                tooltip: { mode: 'index', intersect: false }
            },
            scales: {
                x: { display: true, title: { display: true, text: '시간' } },
                y: {
                    display: true,
                    title: { display: true, text: '실행 횟수' },
                    suggestedMin: 0,
                    beginAtZero: true
                }
            }
        }
    });
};

let dailyJobExecutionsChart;
const renderDailyJobExecutionsChart = (data) => {
    if (dailyJobExecutionsChart) dailyJobExecutionsChart.destroy();

    const ctx = document.getElementById('dailyJobExecutionsChart').getContext('2d');
    const [year, month] = selectedMonth.split('-');
    const firstDay = new Date(year, month - 1, 1);
    const lastDay = new Date(year, month, 0);

    const dates = Array.from({ length: lastDay.getDate() }, (_, i) => 
        new Date(year, month - 1, i + 1).toISOString().split('T')[0]
    );

    const groupedData = data.reduce((acc, item) => {
        const date = item.executionDate.split('T')[0];
        if (!acc[date]) acc[date] = {};
        acc[date][item.jobName] = (acc[date][item.jobName] || 0) + item.executionCount;
        return acc;
    }, {});

    const jobNames = [...new Set(data.map(item => item.jobName))];

    const datasets = jobNames.map(jobName => {
        const color = getRandomColor();
        return {
            label: jobName,
            data: dates.map(date => ({
                x: luxon.DateTime.fromISO(date).toJSDate(),
                y: groupedData[date]?.[jobName] || 0
            })),
            borderColor: color,
            backgroundColor: color,
            fill: false,
            spanGaps: true
        };
    });

    dailyJobExecutionsChart = new Chart(ctx, {
        type: 'line',
        data: { datasets },
        options: {
            ...chartOptions,
            plugins: {
                ...chartOptions.plugins,
                tooltip: {
                    callbacks: {
                        title: (context) => luxon.DateTime.fromJSDate(context[0].parsed.x).toFormat('yyyy-MM-dd')
                    }
                }
            },
            scales: {
                x: {
                    type: 'time',
                    time: { unit: 'day', displayFormats: { day: 'MM-dd' } },
                    title: { display: true, text: '날짜' },
                    min: firstDay,
                    max: lastDay
                },
                y: {
                    beginAtZero: true,
                    title: { display: true, text: '실행 횟수' }
                }
            }
        }
    });
};

const renderRecentJobsTable = (recentJobs) => {
    document.getElementById('recentJobsTable').innerHTML = recentJobs
        .map(({ jobGroup, jobName, firedTime, state }) => `
            <tr>
                <td>${jobGroup}</td>
                <td>${jobName}</td>
                <td>${formatDateTime(firedTime)}</td>
                <td>${state}</td>
            </tr>
        `).join('');
};

const getRandomColor = () => {
    const [r, g, b] = Array.from({ length: 3 }, () => Math.floor(Math.random() * 255));
    return `rgb(${r}, ${g}, ${b})`;
};