const { createCanvas } = require('canvas');
const { Chart } = require('chart.js/auto');
const fs = require('fs');
const { getUserRegistration, getBeatenGames, checkGameStorageId } = require('../../databaseHelperFunctions.js');
const { getGameJson, getGenres } = require('../../igdbHelperFunctions.js');
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
	.setName('chartgamegenres')
	.setDescription('Generate a bar chart of the different genres of the games you have beat')
    .addUserOption(option => option.setName('user').setDescription('The user to check'))
    .addIntegerOption(option => option.setName('year').setDescription('The year to check').addChoices({ name: '2024', value: 2024 }, { name: '2025', value: 2025 }))
    .addBooleanOption(option => option.setName('ignoreadventure').setDescription('Exclude the Adventure genre from the bar chart')),
	async execute(interaction) {

        await interaction.deferReply();

        let user = interaction.user;
        const userOption = interaction.options.getUser('user');
        const yearOption = interaction.options.getInteger('year');
        const ignoreadventure = interaction.options.getBoolean('ignoreadventure');

        if (userOption) {
            user = userOption;
        }

        const userDatabaseEntry = await getUserRegistration(user);
        if (!userDatabaseEntry) return interaction.editReply({ content: `Issue checking registration with "${user.username}".`, ephemeral: true });

        let beatenGamesDatabaseEntries;

        if (yearOption) {
            beatenGamesDatabaseEntries = await getBeatenGames(userDatabaseEntry.id);

            if (beatenGamesDatabaseEntries && beatenGamesDatabaseEntries.length > 0) {
                beatenGamesDatabaseEntries = await beatenGamesDatabaseEntries.filter(entry => {
                    const date = new Date(entry.updatedAt);
                    return date.getFullYear() === yearOption;
                });
            }
        }
        else {
            beatenGamesDatabaseEntries = await getBeatenGames(userDatabaseEntry.id);
        }

        if (!beatenGamesDatabaseEntries || beatenGamesDatabaseEntries.length == 0) {
        const embed = new EmbedBuilder()
        .setTitle(`${user.username}'s beat games age`)
        .setDescription(`${user.username} has not beat any games`)
        .setColor(0xFF0000);
        return interaction.editReply({ embeds: [embed] });
        }

        const beatGameIGDBEntries = [];

        for (let i = 0; i < beatenGamesDatabaseEntries.length; i++) {
            const game = await checkGameStorageId(beatenGamesDatabaseEntries[i].gameId);
            const json = await getGameJson(String.prototype.concat('where id = ', game.igdb_id, '; fields *;'));
            beatGameIGDBEntries.push(json[0]);
        }

        const genres = [];
        const counts = [];
        for (let i = 0; i < beatGameIGDBEntries.length; i++) {
            if (beatGameIGDBEntries[i].genres) {
                for (let j = 0; j < beatGameIGDBEntries[i].genres.length; j++) {
                    const genre = await getGenres(beatGameIGDBEntries[i].genres[j]);
                    genres.push(genre);
                }
            }
        }

        genres.forEach(item => {
            counts[item] = (counts[item] || 0) + 1;
        });

        const sortedCounts = Object.entries(counts).sort((a, b) => b[1] - a[1]);

        const keys = Object.keys(sortedCounts);

        const labels = [];
        const values = [];

        for (let i = 0; i < keys.length; i++) {
            const genre = keys[i];

            if (ignoreadventure && sortedCounts[genre][0] == 'Adventure')
            {
                continue;
            }

            labels.push(sortedCounts[genre][0]);
            values.push(sortedCounts[genre][1]);
        }

        // Create a canvas
        const canvas = createCanvas(1920, 1080);

        // Chart data
        const data = {
        labels: labels,
        datasets: [
            {
            label: 'Game Genres',
            data: values,
            borderColor: '#5865F2',
            backgroundColor: 'rgba(88, 101, 242, 0.5)',
            borderWidth: 8,
            },
        ],
        };

        const config = {
            type: 'bar',
            data: data,
            options: {
                scales: {
                    x: {
                        title: {
                            display: true,
                            text: 'Genres',
                            font: {
                            size: 48,
                            family: 'Tahoma',
                            },
                            color: 'white',
                        },
                        grid: {
                            color: 'rgba(255, 255, 255, 0.5)',
                            lineWidth: 0,
                        },
                        ticks: {
                            color: 'white',
                            font: {
                                size: 24,
                                family: 'Tahoma',
                            },
                        },
                    },
                    y: {
                        beginAtZero: true,
                        title: {
                            display: true,
                            text: 'Occurrences of genre',
                            font: {
                            size: 48,
                            family: 'Tahoma',
                            },
                            color: 'white',
                        },
                        grid: {
                            color: 'rgba(255, 255, 255, 0.5)',
                            lineWidth: 2,
                        },
                        ticks: {
                            stepSize: 1,
                            },
                    },
                },
                plugins: {
                    title: {
                        display: true,
                        text: `${user.username}'s most common game genres`,
                        font: {
                            size: 64,
                            family: 'Tahoma',
                        },
                        color: 'white',
                    },
                },
            },
        };

        // Create the chart
        const chart = new Chart(canvas, config);

        // Save the chart as an image
        const buffer = canvas.toBuffer('image/png');
        fs.writeFileSync('./tempbeattimeline.png', buffer);

        // Use the image in your embed
        return interaction.editReply({
        files: ['./tempbeattimeline.png'],
        });
    },
};