import { AuditLogEvent, GuildAuditLogsEntry, GuildMember } from "discord.js";
import type { NucleusClient } from "../utils/client.js";
import type { LoggerOptions } from "../utils/log.js";
import { generalException } from "../utils/createTemporaryStorage.js";

export const event = "guildMemberUpdate";

export async function callback(client: NucleusClient, before: GuildMember, after: GuildMember) {
    const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger;
    if (before.guild.id === "684492926528651336") {
        await client.database.premium.checkAllPremium(after);
    }

    if (!before.roles.cache.equals(after.roles.cache)) {
        const auditLog = (await getAuditLog(after.guild, AuditLogEvent.MemberRoleUpdate)).filter(
            (entry: GuildAuditLogsEntry) => (entry.target as GuildMember)!.id === after.id
        )[0];
        if (!auditLog) return;
        if (client.noLog.includes(`${after.guild.id}${after.id}${auditLog.id}`)) return;
        generalException(`${after.guild.id}${after.id}${auditLog.id}`);
        if (auditLog.executor!.id !== client.user!.id) {
            const rolesAdded = after.roles.cache.filter((role) => !before.roles.cache.has(role.id));
            const rolesRemoved = before.roles.cache.filter((role) => !after.roles.cache.has(role.id));
            let displayName = "Roles Removed";
            let color = NucleusColors.red;
            let emoji = "GUILD.ROLES.DELETE";
            if (rolesAdded.size > 0 && rolesRemoved.size > 0) {
                displayName = "Roles Changed";
                color = NucleusColors.yellow;
                emoji = "GUILD.ROLES.EDIT";
            } else if (rolesAdded.size > 0) {
                displayName = "Roles Added";
                color = NucleusColors.green;
                emoji = "GUILD.ROLES.CREATE";
            }
            const removedEntry = rolesRemoved.map((role) => role.id);
            const addedEntry = rolesAdded.map((role) => role.id);

            let list = {
                memberId: entry(after.id, `\`${after.id}\``),
                name: entry(after.user.id, renderUser(after.user))
            };

            if (rolesAdded.size > 0) {
                list = Object.assign(list, {
                    rolesAdded: entry(addedEntry, addedEntry.map((id) => `<@&${id}>`).join(", "))
                });
            }
            if (rolesRemoved.size > 0) {
                list = Object.assign(list, {
                    rolesRemoved: entry(removedEntry, removedEntry.map((id) => `<@&${id}>`).join(", "))
                });
            }

            list = Object.assign(list, {
                changed: entry(Date.now(), renderDelta(Date.now())),
                changedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
            });

            let data: LoggerOptions = {
                meta: {
                    type: "memberUpdate",
                    displayName: displayName,
                    calculateType: "guildMemberUpdate",
                    color: color,
                    emoji: emoji,
                    timestamp: Date.now()
                },
                list: {},
                hidden: {
                    guild: after.guild.id
                }
            };

            if (rolesAdded.size > 0) {
                list = Object.assign(list, {
                    rolesAdded: entry(addedEntry, addedEntry.map((id) => `<@&${id}>`).join(", "))
                });
            }
            if (rolesRemoved.size > 0) {
                list = Object.assign(list, {
                    rolesRemoved: entry(removedEntry, removedEntry.map((id) => `<@&${id}>`).join(", "))
                });
            }
            data = Object.assign(data, { list: list });
            log(data);
        }
    }
    const auditLog = (await getAuditLog(after.guild, AuditLogEvent.MemberUpdate)).filter(
        (entry: GuildAuditLogsEntry) => (entry.target as GuildMember)!.id === after.id
    )[0];
    if (!auditLog) return;
    if (auditLog.executor!.id === client.user!.id) return;
    if (before.nickname !== after.nickname) {
        await client.database.history.create(
            "nickname",
            after.guild.id,
            after.user,
            auditLog.executor,
            null,
            before.nickname ?? before.user.username,
            after.nickname ?? after.user.username
        );
        const data = {
            meta: {
                type: "memberUpdate",
                displayName: "Nickname Changed",
                calculateType: "guildMemberUpdate",
                color: NucleusColors.yellow,
                emoji: "PUNISH.NICKNAME.YELLOW",
                timestamp: Date.now()
            },
            list: {
                memberId: entry(after.id, `\`${after.id}\``),
                name: entry(after.user.id, renderUser(after.user)),
                before: entry(before.nickname, before.nickname ? before.nickname : "*None*"),
                after: entry(after.nickname, after.nickname ? after.nickname : "*None*"),
                changed: entry(Date.now(), renderDelta(Date.now())),
                changedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
            },
            hidden: {
                guild: after.guild.id
            }
        };
        log(data);
    }
    if (
        (before.communicationDisabledUntilTimestamp ?? 0) < Date.now() &&
        new Date(after.communicationDisabledUntil ?? 0).getTime() > Date.now()
    ) {
        await client.database.history.create(
            "mute",
            after.guild.id,
            after.user,
            auditLog.executor,
            auditLog.reason,
            null,
            null,
            null
        );
        const data = {
            meta: {
                type: "memberMute",
                displayName: "Muted",
                calculateType: "guildMemberPunish",
                color: NucleusColors.yellow,
                emoji: "PUNISH.MUTE.YELLOW",
                timestamp: Date.now()
            },
            list: {
                memberId: entry(after.id, `\`${after.id}\``),
                name: entry(after.user.id, renderUser(after.user)),
                mutedUntil: entry(
                    after.communicationDisabledUntilTimestamp,
                    renderDelta(after.communicationDisabledUntilTimestamp!)
                ),
                muted: entry(Date.now(), renderDelta(Date.now())),
                mutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!)),
                reason: entry(auditLog.reason, auditLog.reason ? auditLog.reason : "\n> *No reason provided*")
            },
            hidden: {
                guild: after.guild.id
            }
        };
        log(data);
        client.database.eventScheduler.schedule("naturalUnmute", after.communicationDisabledUntil?.toISOString()!, {
            guild: after.guild.id,
            user: after.id,
            expires: after.communicationDisabledUntilTimestamp
        });
    }
    if (
        after.communicationDisabledUntil === null &&
        before.communicationDisabledUntilTimestamp !== null &&
        Date.now() >= auditLog.createdTimestamp
    ) {
        await client.database.history.create(
            "unmute",
            after.guild.id,
            after.user,
            auditLog.executor,
            null,
            null,
            null,
            null
        );
        const data = {
            meta: {
                type: "memberUnmute",
                displayName: "Unmuted",
                calculateType: "guildMemberPunish",
                color: NucleusColors.green,
                emoji: "PUNISH.MUTE.GREEN",
                timestamp: Date.now()
            },
            list: {
                memberId: entry(after.id, `\`${after.id}\``),
                name: entry(after.user.id, renderUser(after.user)),
                unmuted: entry(Date.now(), renderDelta(Date.now())),
                unmutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
            },
            hidden: {
                guild: after.guild.id
            }
        };
        log(data);
        client.database.eventScheduler.cancel("naturalUnmute", {
            guild: after.guild.id,
            user: after.id,
            expires: before.communicationDisabledUntilTimestamp
        });
    }
}
