import type { Guild, GuildMember } from 'discord.js';
import type { NucleusClient } from '../utils/client.js';
//@ts-expect-error
import express from "express";
//@ts-expect-error
import bodyParser from "body-parser";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
//@ts-expect-error
import structuredClone from "@ungap/structured-clone";

const jsonParser = bodyParser.json();
const app = express();
const port = 10000;

const runServer = (client: NucleusClient) => {
    app.get("/", (_req: express.Request, res: express.Response) => {
        res.status(200).send(client.ws.ping);
    });

    app.post("/verify/:code", jsonParser, async function (req: express.Request, res: express.Response) {
        const code = req.params.code;
        const secret = req.body.secret;
        if (secret === client.config.verifySecret) {
            const guild = await client.guilds.fetch(client.verify[code]!.gID) as Guild | null;
            if (!guild) {
                return res.status(404);
            }
            const member = await guild.members.fetch(client.verify[code]!.uID) as GuildMember | null;
            if (!member) {
                return res.status(404);
            }
            if (member.roles.cache.has(client.verify[code]!.rID)) {
                return res.status(200);
            }
            await member.roles.add(client.verify[code]!.rID);

            const interaction = client.verify[code]!.interaction;
            interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setTitle("Verify")
                        .setDescription("Verification complete! You can now dismiss this message")
                        .setStatus("Success")
                        .setEmoji("MEMBER.JOIN")
                ],
                components: []
            });
            client.verify = Object.keys(client.verify)
                .filter((k) => k !== code)
                .reduce((obj, key) => {return { ...obj, [key]: client.verify[key]}}, {});
            const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
            try {
                const data = {
                    meta: {
                        type: "memberVerify",
                        displayName: "Member Verified",
                        calculateType: "guildMemberVerify",
                        color: NucleusColors.green,
                        emoji: "CONTROL.BLOCKTICK",
                        timestamp: Date.now()
                    },
                    list: {
                        member: entry(member.id, renderUser(member.user)),
                        joined: entry(member.joinedTimestamp, renderDelta(member.joinedTimestamp!)),
                        verified: entry(Date.now(), renderDelta(Date.now()))
                    },
                    hidden: {
                        guild: guild.id
                    }
                };
                log(data);
            } catch {
                res.sendStatus(500);
            }
            res.sendStatus(200);
        } else {
            res.sendStatus(403);
        }
    });

    app.get("/verify/:code", jsonParser, function (req: express.Request, res: express.Response) {
        const code = req.params.code;
        if (client.verify[code]) {
            try {
                const interaction = client.verify[code]!.interaction;
                interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setTitle("Verify")
                            .setDescription(
                                "Verify was opened in another tab or window, please complete the check there to continue"
                            )
                            .setStatus("Success")
                            .setEmoji("MEMBER.JOIN")
                    ]
                });
            } catch {
                return res.sendStatus(410);
            }
            const data = structuredClone(client.verify[code]);
            delete data.interaction;
            return res.status(200).send(data);
        }
        return res.sendStatus(404);
    });

    app.post("/rolemenu/:code", jsonParser, async function (req: express.Request, res: express.Response) {
        const code = req.params.code;
        const secret = req.body.secret;
        if (secret === client.config.verifySecret) {
            const guild = await client.guilds.fetch(client.roleMenu[code]!.guild) as Guild | null;
            if (!guild) {
                return res.status(404);
            }
            const member = await guild.members.fetch(client.roleMenu[code]!.user) as GuildMember | null;
            if (!member) {
                return res.status(404);
            }
            res.sendStatus(200);
        } else {
            res.sendStatus(403);
        }
    });

    app.get("/rolemenu/:code", jsonParser, function (req: express.Request, res: express.Response) {
        const code = req.params.code;
        if (client.roleMenu[code] !== undefined) {
            try {
                const interaction = client.roleMenu[code]!.interaction;
                interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setTitle("Roles")
                            .setDescription(
                                "The role menu was opened in another tab or window, please select your roles there to continue"
                            )
                            .setStatus("Success")
                            .setEmoji("GUILD.GREEN")
                    ],
                    components: []
                });
            } catch {
                return res.sendStatus(410);
            }
            const data = structuredClone(client.roleMenu[code]);
            delete data.interaction;
            console.log(data);
            return res.status(200).send(data);
        }
        return res.sendStatus(404);
    });

    app.get("/transcript/:code/human", jsonParser, async function (req: express.Request, res: express.Response) {
        const code = req.params.code;
        if (code === undefined) return res.status(400).send("No code provided");
        const entry = await client.database.transcripts.read(code, req.query.key as string, req.query.iv as string);
        if (entry === null) return res.status(404).send("Could not find a transcript by that code");
        // Convert to a human readable format
        const data = client.database.transcripts.toHumanReadable(entry);
        res.attachment(`${code}.txt`);
        res.type("txt");
        return res.status(200).send(data);
    });

    app.get("/transcript/:code", jsonParser, async function (req: express.Request, res: express.Response) {
        const code = req.params.code;
        if (code === undefined) return res.status(400).send("No code provided");
        const entry = await client.database.transcripts.read(code, req.query.key as string, req.query.iv as string);
        if (entry === null) return res.status(404).send("Could not find a transcript by that code");
        // Convert to a human readable format
        return res.status(200).send(entry);
    });

    app.get("/channels/:id", jsonParser, async function (req: express.Request, res: express.Response) {
        const id = req.params.id;
        if (id === undefined) return res.status(400).send("No id provided");
        const channel = await client.channels.fetch(id);
        if (channel === null) return res.status(404).send("Could not find a channel by that id");
        if (channel.isDMBased()) return res.status(400).send("Cannot get a DM channel");
        return res.status(200).send(channel.name);
    });

    app.get("/users/:id", jsonParser, async function (req: express.Request, res: express.Response) {
        const id = req.params.id;
        if (id === undefined) return res.status(400).send("No id provided");
        let user;
        try {
            user = await client.users.fetch(id);
        } catch (e) {
            console.log(e)
            return res.status(404).send("Could not find a user by that id");
        }
        return res.status(200).send(user.username);
    });

    app.listen(port);
};

export default runServer;
