import type Discord from "discord.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
import type { HaikuClient } from "jshaiku";
export const event = "webhookUpdate";

export async function callback(
    client: HaikuClient,
    channel: Discord.GuildChannel
) {
    try {
        const {
            getAuditLog,
            log,
            NucleusColors,
            entry,
            renderUser,
            renderChannel,
            renderDelta
        } = client.logger;
        let auditLogCreate = getAuditLog(channel.guild, "WEBHOOK_CREATE");
        let auditLogUpdate = getAuditLog(channel.guild, "WEBHOOK_UPDATE");
        let auditLogDelete = getAuditLog(channel.guild, "WEBHOOK_DELETE");
        [auditLogCreate, auditLogUpdate, auditLogDelete] = await Promise.all([
            auditLogCreate,
            auditLogUpdate,
            auditLogDelete
        ]);
        const auditCreate = auditLogCreate.entries
            .filter((entry) => entry.target.channelId === channel.id)
            .first();
        const auditUpdate = auditLogUpdate.entries
            .filter((entry) => entry.target.channelId === channel.id)
            .first();
        const auditDelete = auditLogDelete.entries
            .filter((entry) => entry.target.channelId === channel.id)
            .first();
        if (!auditCreate && !auditUpdate && !auditDelete) return;
        let audit = auditCreate;
        let action = "Create";
        let list = {} as {
            created: { value: string; displayValue: string };
            updated: { value: string; displayValue: string };
            deleted: { value: string; displayValue: string };
        };
        if (
            auditUpdate &&
            auditUpdate.createdTimestamp > audit.createdTimestamp
        ) {
            const { before, after } = auditUpdate.changes.reduce(
                (acc, change) => {
                    acc.before[change.key] = change.old;
                    acc.after[change.key] = change.new;
                    return acc;
                },
                { before: {}, after: {} }
            );
            if (before.name !== after.name)
                list.name = entry(
                    [before.name, after.name],
                    `${before.name} -> ${after.name}`
                );
            if (before.channel_id !== after.channel_id)
                list.channel = entry(
                    [before.channel_id, after.channel_id],
                    renderChannel(
                        await client.channels.fetch(before.channel_id)
                    ) +
                        " -> " +
                        renderChannel(
                            await client.channels.fetch(after.channel_id)
                        )
                );
            if (!Object.keys(list).length) return;
            list.created = entry(
                auditUpdate.target.createdTimestamp,
                renderDelta(auditUpdate.target.createdTimestamp)
            );
            list.edited = entry(
                after.editedTimestamp,
                renderDelta(new Date().getTime())
            );
            list.editedBy = entry(
                auditUpdate.executor.id,
                renderUser(auditUpdate.executor)
            );
            audit = auditUpdate;
            action = "Update";
        } else if (
            auditDelete &&
            auditDelete.createdTimestamp > audit.createdTimestamp
        ) {
            const { before } = auditDelete.changes.reduce(
                (acc, change) => {
                    acc.before[change.key] = change.old;
                    acc.after[change.key] = change.new;
                    return acc;
                },
                { before: {}, after: {} }
            );
            list = {
                name: entry(before.name, `${before.name}`),
                channel: entry(
                    before.channel_id,
                    renderChannel(
                        await client.channels.fetch(before.channel_id)
                    )
                ),
                created: entry(
                    auditDelete.target.createdTimestamp,
                    renderDelta(auditDelete.target.createdTimestamp)
                ),
                deleted: entry(
                    new Date().getTime(),
                    renderDelta(new Date().getTime())
                ),
                deletedBy: entry(
                    auditDelete.executor.id,
                    renderUser(
                        (
                            await channel.guild.members.fetch(
                                auditDelete.executor.id
                            )
                        ).user
                    )
                )
            };
            audit = auditDelete;
            action = "Delete";
        } else {
            const { before } = auditDelete.changes.reduce(
                (acc, change) => {
                    acc.before[change.key] = change.old;
                    acc.after[change.key] = change.new;
                    return acc;
                },
                { before: {}, after: {} }
            );
            list = {
                name: entry(before.name, `${before.name}`),
                channel: entry(
                    before.channel_id,
                    renderChannel(
                        await client.channels.fetch(before.channel_id)
                    )
                ),
                createdBy: entry(
                    auditCreate.executor.id,
                    renderUser(
                        (
                            await channel.guild.members.fetch(
                                auditCreate.executor.id
                            )
                        ).user
                    )
                ),
                created: entry(
                    new Date().getTime(),
                    renderDelta(new Date().getTime())
                )
            };
        }
        const cols = {
            Create: "green",
            Update: "yellow",
            Delete: "red"
        };
        const data = {
            meta: {
                type: "webhook" + action,
                displayName: `Webhook ${action}d`,
                calculateType: "webhookUpdate",
                color: NucleusColors[cols[action]],
                emoji: "WEBHOOK." + action.toUpperCase(),
                timestamp: new Date().getTime()
            },
            list: list,
            hidden: {
                guild: channel.guild.id
            }
        };
        log(data);
    } catch (e) {
        console.log(e);
    }
}
