import { packed } from "magnetar-common";

export type Muted = {
    muted: boolean;
    matched: string[];
    what?: "note" | "reply" | "renote" | "quote";
};

export type NotMuted = { muted: false; matched: string[] };

function checkWordMute(
    note: packed.PackNoteMaybeFull,
    mutedWords: Array<string | string[]>,
): Muted {
    let text = `${note.cw ?? ""} ${note.text ?? ""}`;
    if (note.attachments)
        text += ` ${note.attachments?.map((f) => f.comment ?? "")?.join(" ")}`;
    text = text.trim();

    let result: Muted | NotMuted = { muted: false, matched: [] };

    if (text === "") return result;

    for (const mutePattern of mutedWords) {
        if (Array.isArray(mutePattern)) {
            // Clean up
            const keywords = mutePattern.filter((keyword) => keyword !== "");

            if (
                keywords.length > 0 &&
                keywords.every((keyword) => text.includes(keyword))
            ) {
                result.muted = true;
                result.matched.push(...keywords);
            }
        } else {
            // represents RegExp
            const regexp = mutePattern.match(/^\/(.+)\/(.*)$/);

            // This should never happen due to input sanitisation.
            if (!regexp) {
                console.warn(
                    `Found invalid regex in word mutes: ${mutePattern}`,
                );
                continue;
            }

            try {
                if (new RegExp(regexp[1], regexp[2]).test(text)) {
                    result.muted = true;
                    result.matched.push(mutePattern);
                }
            } catch (err) {
                // This should never happen due to input sanitisation.
            }
        }
    }

    result.matched = [...new Set(result.matched)];
    return result;
}

export function getWordSoftMute(
    note: packed.PackNoteMaybeFull,
    me: Record<string, any> | null | undefined,
    mutedWords: Array<string | string[]>,
): Muted {
    // 自分自身
    if (me && note.user.id === me.id) {
        return { muted: false, matched: [] };
    }

    if (mutedWords.length > 0) {
        let noteMuted = checkWordMute(note, mutedWords);
        if (noteMuted.muted) {
            noteMuted.what = "note";
            return noteMuted;
        }

        if (note.renoted_note) {
            let renoteMuted = checkWordMute(note.renoted_note, mutedWords);
            if (renoteMuted.muted) {
                renoteMuted.what = note.text == null ? "renote" : "quote";
                return renoteMuted;
            }
        }

        if (note.parent_note) {
            let replyMuted = checkWordMute(note.parent_note, mutedWords);
            if (replyMuted.muted) {
                replyMuted.what = "reply";
                return replyMuted;
            }
        }
    }

    return { muted: false, matched: [] };
}
