/*
 * Vencord, a Discord client mod
 * Copyright (c) 2024 Vendicated and contributors
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, CommandContext, sendBotMessage } from "@api/Commands";
import { DataStore } from "@api/index";
import { addAccessory } from "@api/MessageAccessories";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { React, Text } from "@webpack/common";
import { Message } from "discord-types/general";

const flags = new Map<string, Flag>();
type Flag = {
    type: "danger" | "warning" | "info" | "positive";
    text: string;
};

function Flag({ id }: { id: string; }) {
    return (
        <div>
            <Text
                variant="text-md/semibold"
                style={{ color: flags.get(id)?.type === "danger" ? "#FF7473" : flags.get(id)?.type === "warning" ? "#ffb02e" : flags.get(id)?.type === "info" ? "#62A8FF" : "#62FF74" }}
            >
                {flags.get(id)?.type === "danger" ? "🛑" : flags.get(id)?.type === "warning" ? "⚠️" : flags.get(id)?.type === "info" ? "🔵" : "✅"} {flags.get(id)?.text}
            </Text>
        </div>
    );
}

export default definePlugin({
    name: "UserFlags",
    description: `Add "flags" to users that will always show under their messages`,
    authors: [Devs.nin0dev],
    dependencies: ["MessageAccessoriesAPI"],
    async start() {
        const savedFlags = await DataStore.get("USERFLAGS");
        if (savedFlags) {
            const parsedFlags = new Map<string, Flag>(JSON.parse(savedFlags));
            parsedFlags.forEach((value, key) => {
                flags.set(key, value);
            });
        }
        addAccessory("flag", (props: Record<string, any>) => {
            if (flags.has((props.message as Message).author.id)) {
                return <Flag id={props.message.author.id} />;
            }
            return null;
        }, 4);
    },
    commands: [
        {
            name: "flag set",
            description: "Set a flag on a user",
            inputType: ApplicationCommandInputType.BOT,
            options: [
                {
                    name: "user",
                    type: ApplicationCommandOptionType.USER,
                    description: "The user to set a flag to",
                    required: true
                },
                {
                    "name": "type",
                    "type": ApplicationCommandOptionType.STRING,
                    "description": "The type of flag to add",
                    choices: [
                        {
                            label: "Danger",
                            value: "danger",
                            name: "Danger"
                        },
                        {
                            label: "Warning",
                            value: "warning",
                            name: "Warning"
                        },
                        {
                            label: "Info",
                            value: "info",
                            name: "Info"
                        },
                        {
                            label: "Positive",
                            value: "positive",
                            name: "Positive"
                        }
                    ],
                    required: true
                },
                {
                    name: "message",
                    type: ApplicationCommandOptionType.STRING,
                    description: "The flag content",
                    required: true
                },
            ],
            execute: async (args: Argument[], ctx: CommandContext) => {
                flags.set(args[0].value, {
                    type: args[1].value as "danger" | "warning" | "info" | "positive",
                    text: args[2].value
                });
                sendBotMessage(ctx.channel.id, {
                    content: `Flag set on <@${args[0].value}> with content \`${args[2].value}\`!`
                });
                await DataStore.set("USERFLAGS", JSON.stringify(Array.from(flags.entries())));
                return;
            }
        },
        {
            name: "flag delete",
            description: "Delete the flag from a user",
            inputType: ApplicationCommandInputType.BOT,
            options: [
                {
                    name: "user",
                    type: ApplicationCommandOptionType.USER,
                    description: "The user to delete the flag from",
                    required: true
                }
            ],
            execute: async (args: Argument[], ctx: CommandContext) => {
                flags.delete(args[0].value);
                sendBotMessage(ctx.channel.id, {
                    content: `Flag removed from <@${args[0].value}>`
                });
                await DataStore.set("USERFLAGS", JSON.stringify(Array.from(flags.entries())));
                return;
            }
        }
    ]
});

