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) {
        t = Math.floor((t /= 1000));
        return `<t:${t}:D> at <t:${t}:T>`;
    },
    renderDelta(t: number) {
        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);
                channel.send({ embeds: [embed] });
            }
        }
    },
    isLogging
};

export default {};
