import type Discord from "discord.js";
// @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);
    }
}
