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, res) => {
        res.status(200).send(client.ws.ping);
    });

    app.post("/verify/:code", jsonParser, async function (req, res) {
        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);
            if (!guild) {
                return res.status(404);
            }
            const member = await guild.members.fetch(client.verify[code]!.uID);
            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;
            if (interaction) {
                interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setTitle("Verify")
                            .setDescription("Verification complete")
                            .setStatus("Success")
                            .setEmoji("MEMBER.JOIN")
                    ],
                    components: []
                });
            }
            client.verify = client.verify.filter((v) => v.code !== code);
            const { log, NucleusColors, entry, renderUser } = client.logger;
            try {
                const data = {
                    meta: {
                        type: "memberVerify",
                        displayName: "Member Verified",
                        calculateType: "guildMemberVerify",
                        color: NucleusColors.green,
                        emoji: "CONTROL.BLOCKTICK",
                        timestamp: new Date().getTime()
                    },
                    list: {
                        memberId: entry(member.id, `\`${member.id}\``),
                        member: entry(member.id, renderUser(member.user))
                    },
                    hidden: {
                        guild: guild.id
                    }
                };
                log(data);
            } catch {
                res.sendStatus(500);
            }
            res.sendStatus(200);
        } else {
            res.sendStatus(403);
        }
    });

    app.get("/verify/:code", jsonParser, function (req, res) {
        const code = req.params.code;
        if (client.verify[code]) {
            try {
                const interaction = client.verify[code]!.interaction;
                if (interaction) {
                    interaction.editReply({
                        embeds: [
                            new EmojiEmbed()
                                .setTitle("Verify")
                                .setDescription(
                                    "Verify was opened in another tab or window, please complete the CAPTCHA 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, res) {
        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);
            if (!guild) {
                return res.status(404);
            }
            const member = await guild.members.fetch(client.roleMenu[code]!.user);
            if (!member) {
                return res.status(404);
            }
            res.sendStatus(200);
        } else {
            res.sendStatus(403);
        }
    });

    app.get("/rolemenu/:code", jsonParser, function (req, res) {
        const code = req.params.code;
        if (client.roleMenu[code] !== undefined) {
            try {
                const interaction = client.roleMenu[code]!.interaction;
                if (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.listen(port);
};

export default runServer;
