<template>
    <section>
        <header class="_acrylic" @click="shown = !shown">
            <i
                class="toggle ph-fw ph-lg"
                :class="
                    shown
                        ? 'ph-caret-down ph-bold ph-lg'
                        : 'ph-caret-up ph-bold ph-lg'
                "
            ></i>
            <slot></slot> ({{ emojis.length }})
            <span v-if="props.skinToneSelector && props.skinTones">
                <button
                    v-for="skinTone in props.skinTones"
                    class="_button"
                    @click.prevent="
                        applyUnicodeSkinTone(
                            props.skinTones.indexOf(skinTone) + 1,
                        )
                    "
                >
                    <i
                        class="ph-circle ph-fill ph-fw ph-lg"
                        :style="{ color: skinTone + '!important' }"
                    ></i>
                </button>
            </span>
        </header>
        <div v-if="shown" class="body">
            <button
                v-for="emoji in localEmojis"
                :key="emoji"
                class="_button item"
                @click="emit('chosen', emoji, $event)"
            >
                <MagEmoji class="emoji" :emoji="emoji" :normal="true" />
            </button>
        </div>
    </section>
</template>

<script lang="ts" setup>
import { ref, watch, onMounted, toRaw } from "vue";
import { addSkinTone } from "@/scripts/emojilist";
import emojiComponents from "unicode-emoji-json/data-emoji-components.json";
import { types } from "magnetar-common";
import { magConvertReaction, magIsUnicodeEmoji } from "@/scripts-mag/mag-util";
import { instance } from "@/instance";

const props = defineProps<{
    emojis: string[];
    initialShown?: boolean;
    skinToneSelector?: boolean;
    skinTones?: string[];
}>();

const resolveEmojis = (e: string) =>
    magConvertReaction(e, (name) => {
        return instance.emojis.find((e) => e.name === name)?.url!;
    });

const localEmojis = ref<types.Reaction[]>(props.emojis.map(resolveEmojis));

function applyUnicodeSkinTone(custom?: number) {
    for (let i = 0; i < localEmojis.value.length; i++) {
        let rawEmoji: types.ReactionUnicode = toRaw(localEmojis[i]);

        if (!magIsUnicodeEmoji(rawEmoji)) continue;

        if (
            [
                emojiComponents.light_skin_tone,
                emojiComponents.medium_light_skin_tone,
                emojiComponents.medium_skin_tone,
                emojiComponents.medium_dark_skin_tone,
                emojiComponents.dark_skin_tone,
            ].some((v) => rawEmoji.endsWith(v))
        ) {
            rawEmoji = rawEmoji.slice(0, -1);
        }
        localEmojis.value[i] = addSkinTone(rawEmoji, custom);
    }
}

const emit = defineEmits<{
    (ev: "chosen", v: types.Reaction, event: MouseEvent): void;
}>();

const shown = ref(!!props.initialShown);

onMounted(() => {
    if (props.skinToneSelector) {
        applyUnicodeSkinTone();
    }
});

watch(
    () => props.emojis,
    (newVal) => {
        localEmojis.value = newVal.map(resolveEmojis);
    },
);
</script>

<style lang="scss" scoped></style>
