import {
    ButtonStyle,
    CommandInteraction,
    ComponentType,
    GuildMember,
    Message,
    MessageComponentInteraction
} from "discord.js";
import type Discord from "discord.js";
import { Collection, MongoClient } from "mongodb";
import config from "../config/main.js";
import client from "../utils/client.js";
import * as crypto from "crypto";
import _ from "lodash";
import defaultData from "../config/default.js";

const username = encodeURIComponent(config.mongoOptions.username);
const password = encodeURIComponent(config.mongoOptions.password);

const mongoClient = new MongoClient(
    username
        ? `mongodb://${username}:${password}@${config.mongoOptions.host}?authMechanism=DEFAULT`
        : `mongodb://${config.mongoOptions.host}`,
    { authSource: config.mongoOptions.authSource }
);
await mongoClient.connect();
const database = mongoClient.db();

const collectionOptions = { authdb: config.mongoOptions.authSource, w: "majority" };
const getIV = () => crypto.randomBytes(16);

export class Guilds {
    guilds: Collection<GuildConfig>;
    defaultData: GuildConfig;

    constructor() {
        this.guilds = database.collection<GuildConfig>("guilds");
        this.defaultData = defaultData;
    }

    async read(guild: string): Promise<GuildConfig> {
        // console.log("Guild read")
        const entry = await this.guilds.findOne({ id: guild });
        const data = _.cloneDeep(this.defaultData);
        return _.merge(data, entry ?? {});
    }

    async write(guild: string, set: object | null, unset: string[] | string = []) {
        // console.log("Guild write")
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const uo: Record<string, any> = {};
        if (!Array.isArray(unset)) unset = [unset];
        for (const key of unset) {
            uo[key] = null;
        }
        const out = { $set: {}, $unset: {} };
        if (set) out.$set = set;
        if (unset.length) out.$unset = uo;
        await this.guilds.updateOne({ id: guild }, out, { upsert: true });
    }

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    async append(guild: string, key: string, value: any) {
        // console.log("Guild append")
        if (Array.isArray(value)) {
            await this.guilds.updateOne(
                { id: guild },
                {
                    $addToSet: { [key]: { $each: value } }
                },
                { upsert: true }
            );
        } else {
            await this.guilds.updateOne(
                { id: guild },
                {
                    $addToSet: { [key]: value }
                },
                { upsert: true }
            );
        }
    }

    async remove(
        guild: string,
        key: string,
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        value: any,
        innerKey?: string | null
    ) {
        // console.log("Guild remove")
        if (innerKey) {
            await this.guilds.updateOne(
                { id: guild },
                {
                    $pull: { [key]: { [innerKey]: { $eq: value } } }
                },
                { upsert: true }
            );
        } else if (Array.isArray(value)) {
            await this.guilds.updateOne(
                { id: guild },
                {
                    $pullAll: { [key]: value }
                },
                { upsert: true }
            );
        } else {
            await this.guilds.updateOne(
                { id: guild },
                {
                    $pullAll: { [key]: [value] }
                },
                { upsert: true }
            );
        }
    }

    async delete(guild: string) {
        // console.log("Guild delete")
        await this.guilds.deleteOne({ id: guild });
    }
}

interface TranscriptEmbed {
    title?: string;
    description?: string;
    fields?: {
        name: string;
        value: string;
        inline: boolean;
    }[];
    footer?: {
        text: string;
        iconURL?: string;
    };
    color?: number;
    timestamp?: string;
    author?: {
        name: string;
        iconURL?: string;
        url?: string;
    };
}

interface TranscriptComponent {
    type: number;
    style?: ButtonStyle;
    label?: string;
    description?: string;
    placeholder?: string;
    emojiURL?: string;
}

interface TranscriptAuthor {
    username: string;
    discriminator: number;
    nickname?: string;
    id: string;
    iconURL?: string;
    topRole: {
        color: number;
        badgeURL?: string;
    };
    bot: boolean;
}

interface TranscriptAttachment {
    url: string;
    filename: string;
    size: number;
    log?: string;
}

interface TranscriptMessage {
    id: string;
    author: TranscriptAuthor;
    content?: string;
    embeds?: TranscriptEmbed[];
    components?: TranscriptComponent[][];
    editedTimestamp?: number;
    createdTimestamp: number;
    flags?: string[];
    attachments?: TranscriptAttachment[];
    stickerURLs?: string[];
    referencedMessage?: string | [string, string, string]; // the message id, the channel id, the guild id
}

interface TranscriptSchema {
    code: string;
    for: TranscriptAuthor;
    type: "ticket" | "purge";
    guild: string;
    channel: string;
    messages: TranscriptMessage[];
    createdTimestamp: number;
    createdBy: TranscriptAuthor;
}

interface findDocSchema {
    channelID: string;
    messageID: string;
    transcript: string;
}

export class Transcript {
    transcripts: Collection<TranscriptSchema>;
    messageToTranscript: Collection<findDocSchema>;

    constructor() {
        this.transcripts = database.collection<TranscriptSchema>("transcripts");
        this.messageToTranscript = database.collection<findDocSchema>("messageToTranscript");
    }

    async upload(data: findDocSchema) {
        // console.log("Transcript upload")
        await this.messageToTranscript.insertOne(data);
    }

    async create(transcript: Omit<TranscriptSchema, "code">) {
        // console.log("Transcript create")
        let code;
        do {
            code = crypto.randomBytes(64).toString("base64").replace(/=/g, "").replace(/\//g, "_").replace(/\+/g, "-");
        } while (await this.transcripts.findOne({ code: code }));
        const key = crypto
            .randomBytes(32 ** 2)
            .toString("base64")
            .replace(/=/g, "")
            .replace(/\//g, "_")
            .replace(/\+/g, "-")
            .substring(0, 32);
        const iv = getIV().toString("base64").replace(/=/g, "").replace(/\//g, "_").replace(/\+/g, "-");
        for (const message of transcript.messages) {
            if (message.content) {
                const encCipher = crypto.createCipheriv("AES-256-CBC", key, iv);
                message.content = encCipher.update(message.content, "utf8", "base64") + encCipher.final("base64");
            }
        }

        const doc = await this.transcripts.insertOne(Object.assign(transcript, { code: code }), collectionOptions);
        if (doc.acknowledged) {
            client.database.eventScheduler.schedule(
                "deleteTranscript",
                (Date.now() + 1000 * 60 * 60 * 24 * 7).toString(),
                { guild: transcript.guild, code: code, iv: iv, key: key }
            );
            return [code, key, iv];
        } else return [null, null, null];
    }

    async delete(code: string) {
        // console.log("Transcript delete")
        await this.transcripts.deleteOne({ code: code });
    }

    async deleteAll(guild: string) {
        // console.log("Transcript delete")
        const filteredDocs = await this.transcripts.find({ guild: guild }).toArray();
        for (const doc of filteredDocs) {
            await this.transcripts.deleteOne({ code: doc.code });
        }
    }

    async readEncrypted(code: string) {
        // console.log("Transcript read")
        let doc: TranscriptSchema | null = await this.transcripts.findOne({ code: code });
        let findDoc: findDocSchema | null = null;
        if (!doc) findDoc = await this.messageToTranscript.findOne({ transcript: code });
        if (findDoc) {
            const message = await (
                client.channels.cache.get(findDoc.channelID) as Discord.TextBasedChannel | null
            )?.messages.fetch(findDoc.messageID);
            if (!message) return null;
            const attachment = message.attachments.first();
            if (!attachment) return null;
            const transcript = (await fetch(attachment.url)).body;
            if (!transcript) return null;
            const reader = transcript.getReader();
            let data: Uint8Array | null = null;
            let allPacketsReceived = false;
            while (!allPacketsReceived) {
                const { value, done } = await reader.read();
                if (done) {
                    allPacketsReceived = true;
                    continue;
                }
                if (!data) {
                    data = value;
                } else {
                    data = new Uint8Array(Buffer.concat([data, value]));
                }
            }
            if (!data) return null;
            doc = JSON.parse(Buffer.from(data).toString()) as TranscriptSchema;
        }
        if (!doc) return null;
        return doc;
    }

    async read(code: string, key: string, iv: string) {
        // console.log("Transcript read")
        let doc: TranscriptSchema | null = await this.transcripts.findOne({ code: code });
        let findDoc: findDocSchema | null = null;
        if (!doc) findDoc = await this.messageToTranscript.findOne({ transcript: code });
        if (findDoc) {
            const message = await (
                client.channels.cache.get(findDoc.channelID) as Discord.TextBasedChannel | null
            )?.messages.fetch(findDoc.messageID);
            if (!message) return null;
            const attachment = message.attachments.first();
            if (!attachment) return null;
            const transcript = (await fetch(attachment.url)).body;
            if (!transcript) return null;
            const reader = transcript.getReader();
            let data: Uint8Array | null = null;
            // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, no-constant-condition
            while (true) {
                const { value, done } = await reader.read();
                if (done) break;
                if (!data) {
                    data = value;
                } else {
                    data = new Uint8Array(Buffer.concat([data, value]));
                }
            }
            if (!data) return null;
            doc = JSON.parse(Buffer.from(data).toString()) as TranscriptSchema;
        }
        if (!doc) return null;
        for (const message of doc.messages) {
            if (message.content) {
                const decCipher = crypto.createDecipheriv("AES-256-CBC", key, iv);
                message.content = decCipher.update(message.content, "base64", "utf8") + decCipher.final("utf8");
            }
        }
        return doc;
    }

    async createTranscript(
        messages: Message[],
        interaction: MessageComponentInteraction | CommandInteraction,
        member: GuildMember
    ) {
        const interactionMember = await interaction.guild?.members.fetch(interaction.user.id);
        const newOut: Omit<TranscriptSchema, "code"> = {
            type: "ticket",
            for: {
                username: member!.user.username,
                discriminator: parseInt(member!.user.discriminator),
                id: member!.user.id,
                topRole: {
                    color: member!.roles.highest.color
                },
                iconURL: member!.user.displayAvatarURL({ forceStatic: true }),
                bot: member!.user.bot
            },
            guild: interaction.guild!.id,
            channel: interaction.channel!.id,
            messages: [],
            createdTimestamp: Date.now(),
            createdBy: {
                username: interaction.user.username,
                discriminator: parseInt(interaction.user.discriminator),
                id: interaction.user.id,
                topRole: {
                    color: interactionMember?.roles.highest.color ?? 0x000000
                },
                iconURL: interaction.user.displayAvatarURL({ forceStatic: true }),
                bot: interaction.user.bot
            }
        };
        if (member.nickname) newOut.for.nickname = member.nickname;
        if (interactionMember?.roles.icon) newOut.createdBy.topRole.badgeURL = interactionMember.roles.icon.iconURL()!;
        messages.reverse().forEach((message) => {
            const msg: TranscriptMessage = {
                id: message.id,
                author: {
                    username: message.author.username,
                    discriminator: parseInt(message.author.discriminator),
                    id: message.author.id,
                    topRole: {
                        color: message.member!.roles.highest.color
                    },
                    iconURL: message.member!.user.displayAvatarURL({ forceStatic: true }),
                    bot: message.author.bot
                },
                createdTimestamp: message.createdTimestamp
            };
            if (message.member?.nickname) msg.author.nickname = message.member.nickname;
            if (message.member!.roles.icon) msg.author.topRole.badgeURL = message.member!.roles.icon.iconURL()!;
            if (message.content) msg.content = message.content;
            if (message.embeds.length > 0)
                msg.embeds = message.embeds.map((embed) => {
                    const obj: TranscriptEmbed = {};
                    if (embed.title) obj.title = embed.title;
                    if (embed.description) obj.description = embed.description;
                    if (embed.fields.length > 0)
                        obj.fields = embed.fields.map((field) => {
                            return {
                                name: field.name,
                                value: field.value,
                                inline: field.inline ?? false
                            };
                        });
                    if (embed.color) obj.color = embed.color;
                    if (embed.timestamp) obj.timestamp = embed.timestamp;
                    if (embed.footer)
                        obj.footer = {
                            text: embed.footer.text
                        };
                    if (embed.footer?.iconURL) obj.footer!.iconURL = embed.footer.iconURL;
                    if (embed.author)
                        obj.author = {
                            name: embed.author.name
                        };
                    if (embed.author?.iconURL) obj.author!.iconURL = embed.author.iconURL;
                    if (embed.author?.url) obj.author!.url = embed.author.url;
                    return obj;
                });
            if (message.components.length > 0)
                msg.components = message.components.map((component) =>
                    component.components.map((child) => {
                        const obj: TranscriptComponent = {
                            type: child.type
                        };
                        if (child.type === ComponentType.Button) {
                            obj.style = child.style;
                            obj.label = child.label ?? "";
                        } else if (child.type > 2) {
                            obj.placeholder = child.placeholder ?? "";
                        }
                        return obj;
                    })
                );
            if (message.editedTimestamp) msg.editedTimestamp = message.editedTimestamp;
            msg.flags = message.flags.toArray();

            if (message.stickers.size > 0) msg.stickerURLs = message.stickers.map((sticker) => sticker.url);
            if (message.reference)
                msg.referencedMessage = [
                    message.reference.guildId ?? "",
                    message.reference.channelId,
                    message.reference.messageId ?? ""
                ];
            newOut.messages.push(msg);
        });
        return newOut;
    }

    toHumanReadable(transcript: Omit<TranscriptSchema, "code">): string {
        let out = "";
        for (const message of transcript.messages) {
            if (message.referencedMessage) {
                if (Array.isArray(message.referencedMessage)) {
                    out += `> [Crosspost From] ${message.referencedMessage[0]} in ${message.referencedMessage[1]} in ${message.referencedMessage[2]}\n`;
                } else out += `> [Reply To] ${message.referencedMessage}\n`;
            }
            out += `${message.author.nickname ?? message.author.username}#${message.author.discriminator} (${
                message.author.id
            }) (${message.id})`;
            out += ` [${new Date(message.createdTimestamp).toISOString()}]`;
            if (message.editedTimestamp) out += ` [Edited: ${new Date(message.editedTimestamp).toISOString()}]`;
            out += "\n";
            if (message.content) out += `[Content]\n${message.content}\n\n`;
            if (message.embeds) {
                for (const embed of message.embeds) {
                    out += `[Embed]\n`;
                    if (embed.title) out += `| Title: ${embed.title}\n`;
                    if (embed.description) out += `| Description: ${embed.description}\n`;
                    if (embed.fields) {
                        for (const field of embed.fields) {
                            out += `| Field: ${field.name} - ${field.value}\n`;
                        }
                    }
                    if (embed.footer) {
                        out += `|Footer: ${embed.footer.text}\n`;
                    }
                    out += "\n";
                }
            }
            if (message.components) {
                for (const component of message.components) {
                    out += `[Component]\n`;
                    for (const button of component) {
                        out += `| Button: ${button.label ?? button.description}\n`;
                    }
                    out += "\n";
                }
            }
            if (message.attachments) {
                for (const attachment of message.attachments) {
                    out += `[Attachment] ${attachment.filename} (${attachment.size} bytes) ${attachment.url}\n`;
                }
            }
            out += "\n\n";
        }
        return out;
    }
}

export class History {
    histories: Collection<HistorySchema>;

    constructor() {
        this.histories = database.collection<HistorySchema>("history");
    }

    async create(
        type: string,
        guild: string,
        user: Discord.User,
        moderator: Discord.User | null,
        reason: string | null,
        before?: string | null,
        after?: string | null,
        amount?: string | null
    ) {
        // console.log("History create");
        await this.histories.insertOne(
            {
                type: type,
                guild: guild,
                user: user.id,
                moderator: moderator ? moderator.id : null,
                reason: reason,
                occurredAt: new Date(),
                before: before ?? null,
                after: after ?? null,
                amount: amount ?? null
            },
            collectionOptions
        );
    }

    async read(guild: string, user: string, year: number) {
        // console.log("History read");
        const entry = (await this.histories
            .find({
                guild: guild,
                user: user,
                occurredAt: {
                    $gte: new Date(year - 1, 11, 31, 23, 59, 59),
                    $lt: new Date(year + 1, 0, 1, 0, 0, 0)
                }
            })
            .toArray()) as HistorySchema[];
        return entry;
    }

    async delete(guild: string) {
        // console.log("History delete");
        await this.histories.deleteMany({ guild: guild });
    }
}

interface ScanCacheSchema {
    addedAt: Date;
    hash: string;
    data: boolean;
    tags: string[];
}

export class ScanCache {
    scanCache: Collection<ScanCacheSchema>;

    constructor() {
        this.scanCache = database.collection<ScanCacheSchema>("scanCache");
    }

    async read(hash: string) {
        // console.log("ScanCache read");
        return await this.scanCache.findOne({ hash: hash });
    }

    async write(hash: string, data: boolean, tags?: string[]) {
        // console.log("ScanCache write");
        await this.scanCache.insertOne(
            { hash: hash, data: data, tags: tags ?? [], addedAt: new Date() },
            collectionOptions
        );
    }

    async cleanup() {
        // console.log("ScanCache cleanup");
        await this.scanCache.deleteMany({
            addedAt: { $lt: new Date(Date.now() - 1000 * 60 * 60 * 24 * 31) },
            hash: { $not$text: "http" }
        });
    }
}

export class PerformanceTest {
    performanceData: Collection<PerformanceDataSchema>;

    constructor() {
        this.performanceData = database.collection<PerformanceDataSchema>("performance");
    }

    async record(data: PerformanceDataSchema) {
        // console.log("PerformanceTest record");
        data.timestamp = new Date();
        await this.performanceData.insertOne(data, collectionOptions);
    }
    async read() {
        // console.log("PerformanceTest read");
        return await this.performanceData.find({}).toArray();
    }
}

export interface PerformanceDataSchema {
    timestamp?: Date;
    discord: number;
    databaseRead: number;
    resources: {
        cpu: number;
        memory: number;
        temperature: number;
    };
}

export class ModNotes {
    modNotes: Collection<ModNoteSchema>;

    constructor() {
        this.modNotes = database.collection<ModNoteSchema>("modNotes");
    }

    async create(guild: string, user: string, note: string | null) {
        // console.log("ModNotes create");
        await this.modNotes.updateOne({ guild: guild, user: user }, { $set: { note: note } }, { upsert: true });
    }

    async read(guild: string, user: string) {
        // console.log("ModNotes read");
        const entry = await this.modNotes.findOne({ guild: guild, user: user });
        return entry?.note ?? null;
    }

    async delete(guild: string) {
        // console.log("ModNotes delete");
        await this.modNotes.deleteMany({ guild: guild });
    }
}

export class Premium {
    premium: Collection<PremiumSchema>;
    cache: Map<string, [boolean, string, number, boolean, Date]>; // Date indicates the time one hour after it was created
    cacheTimeout = 1000 * 60 * 60; // 1 hour

    constructor() {
        this.premium = database.collection<PremiumSchema>("premium");
        this.cache = new Map<string, [boolean, string, number, boolean, Date]>();
    }

    async updateUser(user: string, level: number) {
        // console.log("Premium updateUser");
        if (!(await this.userExists(user))) await this.createUser(user, level);
        await this.premium.updateOne({ user: user }, { $set: { level: level } }, { upsert: true });
    }

    async userExists(user: string): Promise<boolean> {
        // console.log("Premium userExists");
        const entry = await this.premium.findOne({ user: user });
        return entry ? true : false;
    }
    async createUser(user: string, level: number) {
        // console.log("Premium createUser");
        await this.premium.insertOne({ user: user, appliesTo: [], level: level }, collectionOptions);
    }

    async hasPremium(guild: string): Promise<[boolean, string, number, boolean] | null> {
        // console.log("Premium hasPremium");
        // [Has premium, user giving premium, level, is mod: if given automatically]
        const cached = this.cache.get(guild);
        if (cached && cached[4].getTime() < Date.now()) return [cached[0], cached[1], cached[2], cached[3]];
        const entries = await this.premium.find({}).toArray();
        const members = (await client.guilds.fetch(guild)).members.cache;
        for (const { user } of entries) {
            const member = members.get(user);
            if (member) {
                //TODO: Notify user if they've given premium to a server that has since gotten premium via a mod.
                const modPerms = //TODO: Create list in config for perms
                    member.permissions.has("Administrator") ||
                    member.permissions.has("ManageChannels") ||
                    member.permissions.has("ManageRoles") ||
                    member.permissions.has("ManageEmojisAndStickers") ||
                    member.permissions.has("ManageWebhooks") ||
                    member.permissions.has("ManageGuild") ||
                    member.permissions.has("KickMembers") ||
                    member.permissions.has("BanMembers") ||
                    member.permissions.has("ManageEvents") ||
                    member.permissions.has("ManageMessages") ||
                    member.permissions.has("ManageThreads");
                const entry = entries.find((e) => e.user === member.id);
                if (entry && entry.level === 3 && modPerms) {
                    this.cache.set(guild, [
                        true,
                        member.id,
                        entry.level,
                        true,
                        new Date(Date.now() + this.cacheTimeout)
                    ]);
                    return [true, member.id, entry.level, true];
                }
            }
        }
        const entry = await this.premium.findOne({
            appliesTo: {
                $elemMatch: {
                    $eq: guild
                }
            }
        });
        this.cache.set(guild, [
            entry ? true : false,
            entry?.user ?? "",
            entry?.level ?? 0,
            false,
            new Date(Date.now() + this.cacheTimeout)
        ]);
        return entry ? [true, entry.user, entry.level, false] : null;
    }

    async fetchUser(user: string): Promise<PremiumSchema | null> {
        // console.log("Premium fetchUser");
        const entry = await this.premium.findOne({ user: user });
        if (!entry) return null;
        return entry;
    }

    async checkAllPremium(member?: GuildMember) {
        // console.log("Premium checkAllPremium");
        const entries = await this.premium.find({}).toArray();
        if (member) {
            const entry = entries.find((e) => e.user === member.id);
            if (entry) {
                const expiresAt = entry.expiresAt;
                if (expiresAt) expiresAt < Date.now() ? await this.premium.deleteOne({ user: member.id }) : null;
            }
            const roles = member.roles;
            let level = 0;
            if (roles.cache.has("1066468879309750313")) {
                level = 99;
            } else if (roles.cache.has("1066465491713003520")) {
                level = 1;
            } else if (roles.cache.has("1066439526496604194")) {
                level = 2;
            } else if (roles.cache.has("1066464134322978912")) {
                level = 3;
            }
            await this.updateUser(member.id, level);
            if (level > 0) {
                await this.premium.updateOne({ user: member.id }, { $unset: { expiresAt: "" } });
            } else {
                await this.premium.updateOne(
                    { user: member.id },
                    { $set: { expiresAt: Date.now() + 1000 * 60 * 60 * 24 * 3 } }
                );
            }
        } else {
            const members = await (await client.guilds.fetch("684492926528651336")).members.fetch();
            for (const { roles, id } of members.values()) {
                const entry = entries.find((e) => e.user === id);
                if (entry) {
                    const expiresAt = entry.expiresAt;
                    if (expiresAt) expiresAt < Date.now() ? await this.premium.deleteOne({ user: id }) : null;
                }
                let level: number = 0;
                if (roles.cache.has("1066468879309750313")) {
                    level = 99;
                } else if (roles.cache.has("1066465491713003520")) {
                    level = 1;
                } else if (roles.cache.has("1066439526496604194")) {
                    level = 2;
                } else if (roles.cache.has("1066464134322978912")) {
                    level = 3;
                }
                await this.updateUser(id, level);
                if (level > 0) {
                    await this.premium.updateOne({ user: id }, { $unset: { expiresAt: "" } });
                } else {
                    await this.premium.updateOne(
                        { user: id },
                        { $set: { expiresAt: Date.now() + 1000 * 60 * 60 * 24 * 3 } }
                    );
                }
            }
        }
    }

    async addPremium(user: string, guild: string) {
        // console.log("Premium addPremium");
        const { level } = (await this.fetchUser(user))!;
        this.cache.set(guild, [true, user, level, false, new Date(Date.now() + this.cacheTimeout)]);
        return this.premium.updateOne({ user: user }, { $addToSet: { appliesTo: guild } }, { upsert: true });
    }

    removePremium(user: string, guild: string) {
        // console.log("Premium removePremium");
        this.cache.set(guild, [false, "", 0, false, new Date(Date.now() + this.cacheTimeout)]);
        return this.premium.updateOne({ user: user }, { $pull: { appliesTo: guild } });
    }
}

export interface GuildConfig {
    id: string;
    version: number;
    singleEventNotifications: Record<string, boolean>;
    filters: {
        images: {
            NSFW: boolean;
            size: boolean;
        };
        malware: boolean;
        wordFilter: {
            enabled: boolean;
            words: {
                strict: string[];
                loose: string[];
            };
            allowed: {
                users: string[];
                roles: string[];
                channels: string[];
            };
        };
        invite: {
            enabled: boolean;
            allowed: {
                channels: string[];
                roles: string[];
                users: string[];
            };
        };
        pings: {
            mass: number;
            everyone: boolean;
            roles: boolean;
            allowed: {
                roles: string[];
                rolesToMention: string[];
                users: string[];
                channels: string[];
            };
        };
        clean: {
            channels: string[];
            allowed: {
                users: string[];
                roles: string[];
            };
        };
    };
    autoPublish: {
        enabled: boolean;
        channels: string[];
    };
    welcome: {
        enabled: boolean;
        role: string | null;
        ping: string | null;
        channel: string | null;
        message: string | null;
    };
    stats: Record<string, { name: string; enabled: boolean }>;
    logging: {
        logs: {
            enabled: boolean;
            channel: string | null;
            toLog: string;
        };
        staff: {
            channel: string | null;
        };
        attachments: {
            channel: string | null;
            saved: Record<string, string>;
        };
    };
    verify: {
        enabled: boolean;
        role: string | null;
    };
    tickets: {
        enabled: boolean;
        category: string | null;
        types: string;
        customTypes: string[] | null;
        useCustom: boolean;
        supportRole: string | null;
        maxTickets: number;
    };
    moderation: {
        mute: {
            timeout: boolean;
            role: string | null;
            text: string | null;
            link: string | null;
        };
        kick: {
            text: string | null;
            link: string | null;
        };
        ban: {
            text: string | null;
            link: string | null;
        };
        softban: {
            text: string | null;
            link: string | null;
        };
        warn: {
            text: string | null;
            link: string | null;
        };
        role: {
            role: string | null;
            text: null;
            link: null;
        };
        nick: {
            text: string | null;
            link: string | null;
        };
    };
    tracks: {
        name: string;
        retainPrevious: boolean;
        nullable: boolean;
        track: string[];
        manageableBy: string[];
    }[];
    roleMenu: {
        enabled: boolean;
        allowWebUI: boolean;
        options: {
            name: string;
            description: string;
            min: number;
            max: number;
            options: {
                name: string;
                description: string | null;
                role: string;
            }[];
        }[];
    };
    tags: Record<string, string>;
}

export interface HistorySchema {
    type: string;
    guild: string;
    user: string;
    moderator: string | null;
    reason: string | null;
    occurredAt: Date;
    before: string | null;
    after: string | null;
    amount: string | null;
}

export interface ModNoteSchema {
    guild: string;
    user: string;
    note: string | null;
}

export interface PremiumSchema {
    user: string;
    level: number;
    appliesTo: string[];
    expiresAt?: number;
}
