import { Agenda } from "@hokify/agenda";
import client from "./client.js";
import * as fs from "fs";
import * as path from "path";
import { database } from "./database.js";
import { TextChannel } from "discord.js";

class EventScheduler {
    private agenda: Agenda;

    constructor() {
        this.agenda = new Agenda({
            mongo: database,
            db: {
                collection: "eventScheduler"
            }
        });
        this.agenda.define("unmuteRole", async (job) => {
            const guild = await client.guilds.fetch(job.attrs.data.guild);
            const user = await guild.members.fetch(job.attrs.data.user);
            const role = await guild.roles.fetch(job.attrs.data.role);
            if (role) await user.roles.remove(role);
            await job.remove();
        });
        this.agenda.define("uploadTranscript", async (job) => {
            const channelID: string | null = (await client.database.guilds.read(job.attrs.data.guild)).logging.logs
                .channel;
            if (!channelID) return;
            const channel = await client.channels.fetch(channelID);
            if (!channel || !(channel instanceof TextChannel)) return;
            const transcript = await client.database.transcripts.read(
                job.attrs.data.transcript,
                job.attrs.data.key,
                job.attrs.data.iv
            );
            await client.database.transcripts.delete(job.attrs.data.transcript);
            const file = Buffer.from(JSON.stringify(transcript), "base64");
            const fileName = `${job.attrs.data.transcript}.json`;
            const m = await channel.send({ files: [{ attachment: file, name: fileName }] });
            await client.database.transcripts.upload({
                channelID: channel.id,
                messageID: m.id,
                code: job.attrs.data.transcript
            });
            await job.remove();
        });
        this.agenda.define("deleteFile", async (job) => {
            fs.rm(path.resolve("dist/utils/temp", job.attrs.data.fileName), (e) => {
                client.emit("error", e as Error);
            });
            await job.remove();
        });
        this.agenda.define("naturalUnmute", async (job) => {
            const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
            const guild = await client.guilds.fetch(job.attrs.data.guild);
            const user = await guild.members.fetch(job.attrs.data.user);
            if (user.communicationDisabledUntil === null) return;
            try {
                await client.database.history.create("unmute", user.guild.id, user.user, null, null, null, null);
            } catch (e) {
                client.emit("error", e as Error);
            }
            const data = {
                meta: {
                    type: "memberUnmute",
                    displayName: "Unmuted",
                    calculateType: "guildMemberPunish",
                    color: NucleusColors.green,
                    emoji: "PUNISH.MUTE.GREEN",
                    timestamp: Date.now()
                },
                list: {
                    memberId: entry(user.user.id, `\`${user.user.id}\``),
                    name: entry(user.user.id, renderUser(user.user)),
                    unmuted: entry(Date.now().toString(), renderDelta(Date.now())),
                    unmutedBy: entry(null, "*Time out ended*")
                },
                hidden: {
                    guild: guild.id
                }
            };
            await log(data);
        });
    }

    async start() {
        await new Promise((resolve) => this.agenda.once("ready", resolve));
        await this.agenda.start();
        return this;
    }

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    async schedule(name: string, time: string, data: any) {
        await this.agenda.schedule(time, name, data);
    }

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    async cancel(name: string, data: any) {
        await this.agenda.cancel({ name, data });
    }
}

export default EventScheduler;
