import * as Discord from "discord.js";
import getEmojiByName from "./getEmojiByName.js";
import { toHexArray } from "./calculate.js";
import { promisify } from "util";
import generateKeyValueList from "./generateKeyValueList.js";
import client from "./client.js";
import { DiscordAPIError } from "discord.js";

const wait = promisify(setTimeout);

export interface LoggerOptions {
    meta: {
        type: string;
        displayName: string;
        calculateType: string;
        color: number;
        emoji: string;
        timestamp: number;
    };
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    list: any;
    hidden: {
        guild: string;
    };
    separate?: {
        start?: string;
        end?: string;
    };
}

async function isLogging(guild: string, type: string): Promise<boolean> {
    const config = await client.database.guilds.read(guild);
    if (!config.logging.logs.enabled) return false;
    if (!config.logging.logs.channel) return false;
    if (!toHexArray(config.logging.logs.toLog).includes(type)) {
        return false;
    }
    return true;
}

export const Logger = {
    renderUser(user: Discord.User | string) {
        if (typeof user === "string") user = client.users.cache.get(user)!;
        return `${user.username} [<@${user.id}>]`;
    },
    renderTime(t: number) {
        if (isNaN(t)) return "Unknown";
        t = Math.floor((t /= 1000));
        return `<t:${t}:D> at <t:${t}:T>`;
    },
    renderDelta(t: number) {
        if (isNaN(t)) return "Unknown";
        t = Math.floor((t /= 1000));
        return `<t:${t}:R> (<t:${t}:D> at <t:${t}:T>)`;
    },
    renderNumberDelta(num1: number, num2: number) {
        const delta = num2 - num1;
        return `${num1} -> ${num2} (${delta > 0 ? "+" : ""}${delta})`;
    },
    entry(
        value: string | number | boolean | null | (string | boolean)[],
        displayValue: string
    ): { value: string | boolean | null | (string | boolean | number)[]; displayValue: string } {
        if (typeof value === "number") value = value.toString();
        return { value: value, displayValue: displayValue };
    },
    renderChannel(channel: Discord.GuildChannel | Discord.ThreadChannel | string) {
        if (typeof channel === "string")
            channel = client.channels.cache.get(channel) as Discord.GuildChannel | Discord.ThreadChannel;
        return `${channel.name} [<#${channel.id}>]`;
    },
    renderRole(role: Discord.Role | string, guild?: Discord.Guild | string) {
        if (typeof role === "string")
            role = (typeof guild === "string" ? client.guilds.cache.get(guild) : guild)!.roles.cache.get(role)!;
        return `${role.name} [<@&${role.id}>]`;
    },
    renderEmoji(emoji: Discord.GuildEmoji) {
        return `<${emoji.animated ? "a" : ""}:${emoji.name}:${emoji.id}> [\`:${emoji.name}:\`]`;
    },
    NucleusColors: {
        red: 0xf27878,
        yellow: 0xf2d478,
        green: 0x68d49e
    },
    async getAuditLog(
        guild: Discord.Guild,
        event: Discord.GuildAuditLogsResolvable,
        delay?: number
    ): Promise<Discord.GuildAuditLogsEntry[]> {
        if (!guild.members.me?.permissions.has("ViewAuditLog")) return [];
        await wait(delay ?? 250);
        try {
            const auditLog = (await guild.fetchAuditLogs({ type: event })).entries.map((m) => m);
            return auditLog as Discord.GuildAuditLogsEntry[];
        } catch (e) {
            if (e instanceof DiscordAPIError) return [];
            throw e;
        }
    },
    async log(log: LoggerOptions): Promise<void> {
        if (!(await isLogging(log.hidden.guild, log.meta.calculateType))) return;
        console.log(log.hidden.guild);
        const config = await client.database.guilds.read(log.hidden.guild);
        console.log(config.logging.logs.channel);

        if (config.logging.logs.channel) {
            const channel = (await client.channels.fetch(config.logging.logs.channel)) as Discord.TextChannel | null;
            const description: Record<string, string> = {};
            Object.entries(log.list).map((entry) => {
                const key: string = entry[0];
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                const value: any = entry[1];
                if (value.displayValue) {
                    description[key] = value.displayValue;
                } else {
                    description[key] = value;
                }
            });
            if (channel) {
                log.separate = log.separate ?? {};
                const embed = new Discord.EmbedBuilder()
                    .setTitle(`${getEmojiByName(log.meta.emoji)} ${log.meta.displayName}`)
                    .setDescription(
                        (log.separate.start ? log.separate.start + "\n" : "") +
                            generateKeyValueList(description) +
                            (log.separate.end ? "\n" + log.separate.end : "")
                    )
                    .setTimestamp(log.meta.timestamp)
                    .setColor(log.meta.color);
                await channel.send({ embeds: [embed] });
            }
        }
    },
    isLogging
};

export default {};
