import {BaseInteraction, Client} from "discord.js"
import {config} from "dotenv"
import {isChatInputCommand} from "./types/interactions.js"
import {commandDefinitions, executeCommand, storeCachedCommands} from "./commands/index.js"
import {checkIsRestart, reportFailed, reportReady, reportStarted} from "./ipc/restart.js"
import {defaultPresence} from "./defaultPresence.js"

async function main() {
    await checkIsRestart()
    config()
    const c = new Client({
        intents: [],
    })
    c.on("ready", async () => {
        const app = c.application
        if (!app) {
            c.destroy()
            await reportFailed(c, "No application was given")
            return
        } else {
            try {
                storeCachedCommands(await app.commands.set(commandDefinitions))
                const g = await c.guilds.fetch()
                for (const guild of g.values()) {
                    storeCachedCommands(await app.commands.set(commandDefinitions, guild.id))
                }
            } catch (ex) {
                c.destroy()
                await reportFailed(c, ex)
                return
            }
        }
        const user = c.user
        if (!user) {
            c.destroy()
            await reportFailed(c, "No user found")
            return
        } else {
            user.setPresence(defaultPresence)
        }
        try {
            await reportReady(c)
        } catch (ex) {
            console.log(ex)
        }
    })
    c.on("error", async (ex) => {
        c.destroy()
        await reportFailed(c, ex)
    })
    c.on("interactionCreate", async (ev: BaseInteraction) => {
        if (ev.client.user.presence.status !== "online") {
            if (ev.isRepliable()) {
                try {
                    await ev.reply({
                        content: "Shhh... I'm sleeping!! Try again later.",
                        ephemeral: true,
                    })
                } catch (ex) {
                    console.log("failed sending busy reply", ex)
                }
            }
            return
        }
        if (isChatInputCommand(ev)) {
            try {
                await executeCommand(ev)
            } catch (ex) {
                console.log("failed executing command", ev, ex)
                if (!ev.replied) {
                    try {
                        await ev.reply({
                            ephemeral: true,
                            content: "Uuguuu... I can't think straight... try again later, 'kay?",
                        })
                    } catch (innerEx) {
                        console.log("failed sending error response", innerEx)
                    }
                }
            }
        } else if (ev.isRepliable()) {
            try {
                await ev.reply({
                    ephemeral: true,
                    content: "Huuuuuuuh? ... I don't know what to do with that yet.",
                })
            } catch (ex) {
                console.log("failed sending unknown command response", ex)
            }
        } else {
            console.log("got an interaction but can't reply to it")
        }
    })
    await reportStarted()
    await c.login(process.env.DISCORD_TOKEN || "")
}

main().catch((ex) => {
    console.log("main thread failed", ex)
})