import type { NucleusClient } from "../utils/client.js";
import { LinkCheck, MalwareCheck, NSFWCheck, SizeCheck, TestString, TestImage } from "../reflex/scanners.js";
import logAttachment from "../premium/attachmentLogs.js";
import { messageException } from "../utils/createTemporaryStorage.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import client from "../utils/client.js";
import { callback as statsChannelUpdate } from "../reflex/statsChannelUpdate.js";
import { ChannelType, GuildMember, Message, ThreadChannel } from "discord.js";
import singleNotify from "../utils/singleNotify.js";

export const event = "messageCreate";

function checkUserForExceptions(user: GuildMember, exceptions: { roles: string[]; users: string[] }) {
    if (exceptions.users.includes(user.id)) return true;
    for (const role of user.roles.cache.values()) {
        if (exceptions.roles.includes(role.id)) return true;
    }
    return false;
}

export async function callback(_client: NucleusClient, message: Message) {
    if (!message.guild) return;
    const config = await client.memory.readGuildInfo(message.guild.id);

    if (
        config.autoPublish.enabled &&
        config.autoPublish.channels.includes(message.channel.id) &&
        message.channel.type === ChannelType.GuildAnnouncement &&
        message.reference === null
    ) {
        if (message.channel.permissionsFor(message.guild.members.me!)!.has("ManageMessages")) {
            await message.crosspost();
        } else {
            await singleNotify(
                `Nucleus does not have Manage Messages in <#${message.channel.id}>`,
                message.guild.id,
                true
            );
        }
    }

    if (message.author.bot) return;
    if (message.channel.isDMBased()) return;
    try {
        await statsChannelUpdate((await message.guild.members.fetch(message.author.id)).user, message.guild);
    } catch (e) {
        console.log(e);
    }

    const { log, isLogging, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;

    const fileNames = await logAttachment(message);

    const content = message.content.toLowerCase() || "";
    if (config.filters.clean.channels.includes(message.channel.id)) {
        if (!checkUserForExceptions(message.member!, config.filters.clean.allowed)) return await message.delete();
    }

    const filter = getEmojiByName("ICONS.FILTER");
    let attachmentJump = "";
    if (config.logging.attachments.saved[message.channel.id + message.id]) {
        attachmentJump = ` [[View attachments]](${config.logging.attachments.saved[message.channel.id + message.id]})`;
    }
    const list = {
        messageId: entry(message.id, `\`${message.id}\``),
        sentBy: entry(message.author.id, renderUser(message.author)),
        sentIn: entry(message.channel.id, renderChannel(message.channel)),
        deleted: entry(Date.now(), renderDelta(Date.now())),
        mentions: message.mentions.users.size,
        attachments: entry(message.attachments.size, message.attachments.size + attachmentJump),
        repliedTo: entry(
            (message.reference ? message.reference.messageId : null) ?? null,
            message.reference
                ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})`
                : "None"
        )
    };

    if (config.filters.invite.enabled) {
        if (
            !config.filters.invite.allowed.channels.includes(message.channel.id) ||
            !checkUserForExceptions(message.member!, config.filters.invite.allowed)
        ) {
            if (/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content)) {
                messageException(message.guild.id, message.channel.id, message.id);
                await message.delete();
                const data = {
                    meta: {
                        type: "messageDelete",
                        displayName: "Message Deleted",
                        calculateType: "autoModeratorDeleted",
                        color: NucleusColors.red,
                        emoji: "MESSAGE.DELETE",
                        timestamp: Date.now()
                    },
                    separate: {
                        start:
                            filter +
                            " Contained invite\n\n" +
                            (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
                    },
                    list: list,
                    hidden: {
                        guild: message.channel.guild.id
                    }
                };
                return log(data);
            }
        }
    }

    if (fileNames.files.length > 0) {
        for (const element of fileNames.files) {
            const url = element.url ? element.url : element.local;
            if (
                /\.(jpg|jpeg|png|apng|gif|gifv|webm|webp|mp4|wav|mp3|ogg|jfif|mpeg-\d|avi|h\.264|h\.265)$/.test(
                    url.toLowerCase()
                )
            ) {
                // j(pe?g|fif)|a?png|gifv?|w(eb[mp]|av)|mp([34]|eg-\d)|ogg|avi|h\.26(4|5)
                // ^no
                if (
                    config.filters.images.NSFW &&
                    !(message.channel instanceof ThreadChannel ? message.channel.parent?.nsfw : message.channel.nsfw) &&
                    (await NSFWCheck(element.url))
                ) {
                    messageException(message.guild.id, message.channel.id, message.id);
                    await message.delete();
                    const data = {
                        meta: {
                            type: "messageDelete",
                            displayName: "Message Deleted",
                            calculateType: "autoModeratorDeleted",
                            color: NucleusColors.red,
                            emoji: "MESSAGE.DELETE",
                            timestamp: Date.now()
                        },
                        separate: {
                            start:
                                filter +
                                " Image detected as NSFW\n\n" +
                                (content
                                    ? `**Message:**\n\`\`\`${content}\`\`\``
                                    : "**Message:** *Message had no content*")
                        },
                        list: list,
                        hidden: {
                            guild: message.channel.guild.id
                        }
                    };
                    return log(data);
                }
                if (config.filters.wordFilter.enabled) {
                    const text = await TestImage(url);
                    const check = TestString(
                        text ?? "",
                        config.filters.wordFilter.words.loose,
                        config.filters.wordFilter.words.strict
                    );
                    if (
                        check !== null &&
                        (!checkUserForExceptions(message.member!, config.filters.wordFilter.allowed) ||
                            !config.filters.wordFilter.allowed.channels.includes(message.channel.id))
                    ) {
                        messageException(message.guild.id, message.channel.id, message.id);
                        await message.delete();
                        const data = {
                            meta: {
                                type: "messageDelete",
                                displayName: "Message Deleted",
                                calculateType: "autoModeratorDeleted",
                                color: NucleusColors.red,
                                emoji: "MESSAGE.DELETE",
                                timestamp: Date.now()
                            },
                            separate: {
                                start:
                                    filter +
                                    " Image contained filtered word\n\n" +
                                    (content
                                        ? `**Message:**\n\`\`\`${content}\`\`\``
                                        : "**Message:** *Message had no content*")
                            },
                            list: list,
                            hidden: {
                                guild: message.channel.guild.id
                            }
                        };
                        return log(data);
                    }
                }
                if (config.filters.images.size) {
                    if (url.match(/\.+(webp|png|jpg)$/gi)) {
                        if (!(await SizeCheck(element))) {
                            messageException(message.guild.id, message.channel.id, message.id);
                            await message.delete();
                            const data = {
                                meta: {
                                    type: "messageDelete",
                                    displayName: "Message Deleted",
                                    calculateType: "autoModeratorDeleted",
                                    color: NucleusColors.red,
                                    emoji: "MESSAGE.DELETE",
                                    timestamp: Date.now()
                                },
                                separate: {
                                    start:
                                        filter +
                                        " Image was too small\n\n" +
                                        (content
                                            ? `**Message:**\n\`\`\`${content}\`\`\``
                                            : "**Message:** *Message had no content*")
                                },
                                list: list,
                                hidden: {
                                    guild: message.channel.guild.id
                                }
                            };
                            return log(data);
                        }
                    }
                }
            }
            if (config.filters.malware && (await MalwareCheck(url))) {
                messageException(message.guild.id, message.channel.id, message.id);
                await message.delete();
                const data = {
                    meta: {
                        type: "messageDelete",
                        displayName: "Message Deleted",
                        calculateType: "autoModeratorDeleted",
                        color: NucleusColors.red,
                        emoji: "MESSAGE.DELETE",
                        timestamp: Date.now()
                    },
                    separate: {
                        start:
                            filter +
                            " File detected as malware\n\n" +
                            (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
                    },
                    list: list,
                    hidden: {
                        guild: message.channel.guild.id
                    }
                };
                return log(data);
            }
        }
    }

    const linkDetectionTypes = await LinkCheck(message);
    if (linkDetectionTypes.length > 0) {
        messageException(message.guild.id, message.channel.id, message.id);
        await message.delete();
        const data = {
            meta: {
                type: "messageDelete",
                displayName: "Message Deleted",
                calculateType: "autoModeratorDeleted",
                color: NucleusColors.red,
                emoji: "MESSAGE.DELETE",
                timestamp: Date.now()
            },
            separate: {
                start:
                    filter +
                    ` Link filtered as ${linkDetectionTypes[0]?.toLowerCase()}\n\n` +
                    (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
            },
            list: list,
            hidden: {
                guild: message.channel.guild.id
            }
        };
        return log(data);
    }

    if (
        config.filters.wordFilter.enabled &&
        (!checkUserForExceptions(message.member!, config.filters.wordFilter.allowed) ||
            !config.filters.wordFilter.allowed.channels.includes(message.channel.id))
    ) {
        const check = TestString(
            content,
            config.filters.wordFilter.words.loose,
            config.filters.wordFilter.words.strict
        );
        if (check !== null) {
            messageException(message.guild.id, message.channel.id, message.id);
            await message.delete();
            const data = {
                meta: {
                    type: "messageDelete",
                    displayName: "Message Deleted",
                    calculateType: "autoModeratorDeleted",
                    color: NucleusColors.red,
                    emoji: "MESSAGE.DELETE",
                    timestamp: Date.now()
                },
                separate: {
                    start:
                        filter +
                        " Message contained filtered word\n\n" +
                        (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
                },
                list: list,
                hidden: {
                    guild: message.channel.guild.id
                }
            };
            return log(data);
        }
    }

    if (
        config.filters.pings.everyone &&
        message.mentions.everyone &&
        !checkUserForExceptions(message.member!, config.filters.pings.allowed)
    ) {
        if (!(await isLogging(message.guild.id, "messageMassPing"))) return;
        const data = {
            meta: {
                type: "everyonePing",
                displayName: "Everyone Pinged",
                calculateType: "messageMassPing",
                color: NucleusColors.yellow,
                emoji: "MESSAGE.PING.EVERYONE",
                timestamp: Date.now()
            },
            separate: {
                start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
            },
            list: list,
            hidden: {
                guild: message.channel.guild.id
            }
        };
        return log(data);
    }
    if (config.filters.pings.roles && !checkUserForExceptions(message.member!, config.filters.pings.allowed)) {
        for (const roleId in message.mentions.roles) {
            if (!config.filters.pings.allowed.roles.includes(roleId)) {
                messageException(message.guild.id, message.channel.id, message.id);
                await message.delete();
                if (!(await isLogging(message.guild.id, "messageMassPing"))) return;
                const data = {
                    meta: {
                        type: "rolePing",
                        displayName: "Role Pinged",
                        calculateType: "messageMassPing",
                        color: NucleusColors.yellow,
                        emoji: "MESSAGE.PING.ROLE",
                        timestamp: Date.now()
                    },
                    separate: {
                        start: content
                            ? `**Message:**\n\`\`\`${content}\`\`\``
                            : "**Message:** *Message had no content*"
                    },
                    list: list,
                    hidden: {
                        guild: message.channel.guild.id
                    }
                };
                return log(data);
            }
        }
    }
    if (
        message.mentions.users.size >= config.filters.pings.mass &&
        config.filters.pings.mass &&
        !checkUserForExceptions(message.member!, config.filters.pings.allowed)
    ) {
        messageException(message.guild.id, message.channel.id, message.id);
        await message.delete();
        if (!(await isLogging(message.guild.id, "messageMassPing"))) return;
        const data = {
            meta: {
                type: "massPing",
                displayName: "Mass Ping",
                calculateType: "messageMassPing",
                color: NucleusColors.yellow,
                emoji: "MESSAGE.PING.MASS",
                timestamp: Date.now()
            },
            separate: {
                start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
            },
            list: list,
            hidden: {
                guild: message.channel.guild.id
            }
        };
        return log(data);
    }
}
