const { SlashCommandBuilder } = require('@discordjs/builders');
const { AttachmentBuilder } = require("discord.js");
const fs = require('node:fs');
const { submissions, commands } = require("../config/config.js");
const { parse } = require("csv-parse/sync");
const { getSubmissionLine, safeCsvFormat } = require("../common.js");
const Sugar = require("sugar-date");
const { Buffer } = require("buffer");

/**
 * @param {import('discord.js').ChatInputCommandInteraction} interaction
 */
async function execute(interaction) {
    const game = interaction.options.getString("game", true);

    const fname = submissions[game];
    if (fname === undefined) {
        await interaction.reply({content: "Invalid game specified!", ephemeral: true});
        return;
    }

    if (!fs.existsSync(fname)) {
        await interaction.reply(`No submissions exist yet for ${game}.`);
        return;
    }

    const afterDateStr = interaction.options.getString("after_date");
    const beforeDateStr = interaction.options.getString("before_date");
    let afterTimestamp = undefined;
    let beforeTimestamp = undefined;
    
    // Using Sugar for magic date parsing
    if (afterDateStr) {
        const afterDate = Sugar.Date.create(afterDateStr);
        if (isNaN(afterDate)) {
            await interaction.reply({content: `Could not convert '${afterDateStr}' to a valid date.`, ephemeral: true});
            return;
        }
        afterTimestamp = Math.round(afterDate / 1000);
    }

    if (beforeDateStr) {
        const beforeDate = Sugar.Date.create(beforeDateStr);
        if (isNaN(beforeDate)) {
            await interaction.reply({content: `Could not convert '${beforeDateStr}' to a valid date.`, ephemeral: true});
            return;
        }
        beforeTimestamp = Math.round(beforeDate / 1000);
    }

    if (!isNaN(afterTimestamp) && !isNaN(beforeTimestamp) && beforeTimestamp < afterTimestamp) {
        await interaction.reply({content: `Your date range is invalid: ${getDateRangeString(afterTimestamp, beforeTimestamp)}.`, ephemeral: true});
        return;
    }

    const csvFile = fs.readFileSync(fname);

    const lines = parse(csvFile, {delimiter: ',', fromLine: 2});

    let csvString = "map_id,unix_timestamp,date_string,user_id,username,display_name,creator\n";
    let found = false;
    for (let lineStr of lines) {
        const line = getSubmissionLine(lineStr);
        
        // Must be between the given date range
        if ((!isNaN(afterTimestamp) && line.timestamp < afterTimestamp) ||
            (!isNaN(beforeTimestamp) && line.timestamp > beforeTimestamp)) {
            continue;
        }

        found = true;
        const dateStr = new Date(line.timestamp * 1000).toLocaleString("en-US", {dateStyle: "short"});
        csvString += `${line.modelId},${line.timestamp},${dateStr},${line.userId},${safeCsvFormat(line.username)},${safeCsvFormat(line.displayName)},${safeCsvFormat(line.creator)}\n`;
    }

    if (!found) {
        let msg;
        const dateRangeStr = getDateRangeString(afterTimestamp, beforeTimestamp);
        if (dateRangeStr) {
            msg = `Could not find any submissions ${dateRangeStr}.`;
        }
        else {
            msg = "Could not find any submissions.";
        }
        await interaction.reply({content: msg, ephemeral: true});
        return;
    }

    const file = new AttachmentBuilder(Buffer.from(csvString), { name: fname });
    const dateRangeStr = getDateRangeString(afterTimestamp, beforeTimestamp);
    if (dateRangeStr) {
        await interaction.reply({content: `Using date range ${dateRangeStr}:`, files: [file]});
    }
    else {
        await interaction.reply({files: [file]});
    }
}

function getDateRangeString(afterTimestamp, beforeTimestamp) {
    if (!isNaN(afterTimestamp) && !isNaN(beforeTimestamp)) {
        return `between <t:${afterTimestamp}:d> to <t:${beforeTimestamp}:d>`;
    }
    else if (!isNaN(afterTimestamp)) {
        return `after <t:${afterTimestamp}:d>`;
    }
    else if (!isNaN(beforeTimestamp)) {
        return `before <t:${beforeTimestamp}:d>`;
    }
    else {
        return "";
    }
}

module.exports = {
	data: new SlashCommandBuilder()
		.setName('submissions')
		.setDescription('View the submissions in .csv format')
        .addStringOption(option =>
            option.setName("game")
            .setDescription("Select the maptest game")
            .setRequired(true)
            .addChoices(...commands))
        .addStringOption(option =>
            option.setName("after_date")
            .setDescription("Filter out submissions that weren't submitted after the given date"))
        .addStringOption(option =>
            option.setName("before_date")
            .setDescription("Filter out submissions that weren't submitted before the given date"))
        ,
	execute
};