<script setup lang="ts">
import { Ref, computed, ref } from 'vue';
import Button from 'primevue/button';
import Dialog from 'primevue/dialog';
import Fieldset from 'primevue/fieldset';
import InputText from 'primevue/inputtext';
import SelectButton from 'primevue/selectbutton';
import ToggleSwitch from 'primevue/toggleswitch';
import ModListEntry from './ModListEntry.vue';
import ModTitlecard from './ModTitlecard.vue';
import { invoke } from '../invoke';
import { useClientStore, usePkgStore, usePrfStore } from '../stores';
import { Game, Package } from '../types';
import { pkgKey } from '../util';
import { useI18n } from 'vue-i18n';

const { t } = useI18n();

const props = defineProps({
    search: String,
});

const pkgs = usePkgStore();
const client = useClientStore();
const prf = usePrfStore();
const gameSublist: Ref<string[]> = ref([]);

const loadPackages = () => {
    invoke('get_game_packages', {
        game: prf.current?.meta.game ?? null,
    }).then((list) => {
        gameSublist.value = list as string[];
    });
};

loadPackages();

const group = computed(() => {
    const grouped = Object.groupBy(
        pkgs.allLocal
            .filter((p) => gameSublist.value.includes(pkgKey(p)))
            .filter(
                (p) =>
                    props.search === undefined ||
                    p.name.toLowerCase().includes(props.search.toLowerCase()) ||
                    p.namespace
                        .toLowerCase()
                        .includes(props.search.toLowerCase())
            ),
        ({ namespace }) => namespace
    );
    if (!('local' in grouped)) {
        grouped['local'] = [];
    }
    const res: [string, Package[]][] = [];
    for (const [k, v] of Object.entries(grouped)) {
        if (v !== undefined) {
            res.push([k, v]);
        }
    }
    res.sort((a, b) => {
        return a[0] === 'local'
            ? -1000
            : b[0] === 'local'
              ? 1000
              : `${a[0]}`.localeCompare(`${b[0]}`);
    });

    return res;
});

const missing = computed(() => {
    return prf.current?.data.mods.filter((m) => !pkgs.hasLocal(m)) ?? [];
});

const dialogVisible = ref(false);

const defaultModel = {
    name: '',
    description: '',
    website: '',
    type: 'rainy',
    games: [] as string[],
};

const creatorModel = ref({ ...defaultModel });

const gameModel = (game: Game) =>
    computed({
        get() {
            return (creatorModel.value.games as string[]).includes(game);
        },
        set(v: boolean) {
            creatorModel.value.games = creatorModel.value.games.filter(
                (g) => g !== game
            );
            if (v) {
                creatorModel.value.games.push(game);
            }
        },
    });
const gameModelOngeki = gameModel('ongeki');
const gameModelChunithm = gameModel('chunithm');
</script>

<template>
    <Dialog
        modal
        :visible="dialogVisible"
        :closable="false"
        :header="t('creator.header')"
        :style="{ width: '500px', scale: client.scaleValue }"
        class="creation-dialog"
    >
        <div style="position: absolute; left: 250px; top: 25px">
            <a
                href="https://gitea.tendokyu.moe/akanyan/STARTLINER/wiki/Package-format"
                target="_blank"
                style="text-decoration: underline"
                class="self-center"
                >{{ t('creator.packageFormat') }}</a
            >
        </div>
        <h2>{{ t('creator.basic') }}</h2>
        <div class="flex flex-col gap-3">
            <InputText
                size="small"
                style="width: 100%"
                :placeholder="t('creator.name')"
                v-model="creatorModel.name"
            />
            <InputText
                size="small"
                style="width: 100%"
                :placeholder="t('creator.description')"
                v-model="creatorModel.description"
            />
            <InputText
                size="small"
                style="width: 100%"
                :placeholder="t('creator.website')"
                v-model="creatorModel.website"
            />
        </div>

        <h2>{{ t('creator.type') }}</h2>
        <div class="flex flex-col items-center">
            <SelectButton
                :options="[
                    { title: t('creator.rainy'), value: 'rainy' },
                    { title: t('creator.native'), value: 'native' },
                    { title: t('creator.segatools'), value: 'segatools' },
                ]"
                v-model="creatorModel.type"
                :allow-empty="false"
                option-label="title"
                option-value="value"
            />
        </div>

        <h2>{{ t('creator.games') }}</h2>
        <div class="flex flex-col gap-4">
            <div class="flex flex-row">
                <div class="grow">{{ t('game.ongeki') }}</div>
                <ToggleSwitch v-model="gameModelOngeki" />
            </div>
            <div class="flex flex-row">
                <div class="grow">{{ t('game.chunithm') }}</div>
                <ToggleSwitch v-model="gameModelChunithm" />
            </div>
        </div>

        <div class="flex flex-row mt-5">
            <Button
                class="ml-auto mr-1"
                style="width: 80px"
                :label="t('ok')"
                :disabled="creatorModel.games.length === 0"
                @click="
                    async () => {
                        await invoke('create_package', creatorModel);
                        await pkgs.reloadAll();
                        loadPackages();
                        dialogVisible = false;
                        creatorModel = { ...defaultModel };
                    }
                "
            />
            <Button
                class="mr-auto ml-1"
                style="width: 80px"
                :label="t('cancel')"
                @click="
                    () => (
                        (dialogVisible = false),
                        (creatorModel = { ...defaultModel })
                    )
                "
            />
        </div>
    </Dialog>
    <Fieldset :legend="t('store.missing')" v-if="(missing?.length ?? 0) > 0">
        <div class="flex items-center" v-for="p in missing">
            <ModTitlecard
                show-namespace
                :pkg="
                    {
                        namespace: p.split('-')[0],
                        name: p.split('-')[1],
                    } as Package
                "
            />
            <Button
                rounded
                icon="pi pi-minus"
                severity="danger"
                aria-label="install"
                size="small"
                class="self-center ml-4"
                style="width: 2rem; height: 2rem"
                v-on:click="prf.togglePkg(p, false)"
            />
        </div>
    </Fieldset>
    <Fieldset v-for="[namespace, pkgs] in group" :legend="namespace">
        <ModListEntry v-for="p in pkgs" :pkg="p" />
        <div v-if="namespace === 'local'">
            <Button
                rounded
                icon="pi pi-plus"
                severity="success"
                aria-label="install"
                size="small"
                class="self-center"
                style="width: 2rem; height: 2rem"
                v-on:click="() => (dialogVisible = true)"
            />
        </div>
    </Fieldset>
</template>

<style lang="css" scoped>
.creation-dialog h2 {
    margin-top: 0.6em;
    margin-bottom: 0.4em;
    font-size: 110%;
}
</style>
