<script setup lang="ts">
import { Ref, computed, ref } from 'vue';
import Button from 'primevue/button';
import ContextMenu from 'primevue/contextmenu';
import { useConfirm } from 'primevue/useconfirm';
import { listen } from '@tauri-apps/api/event';
import { getCurrentWindow } from '@tauri-apps/api/window';
import { invoke } from '../invoke';
import { usePrfStore } from '../stores';

const prf = usePrfStore();
const confirmDialog = useConfirm();

type StartStatus = 'ready' | 'preparing' | 'running';
const startStatus: Ref<StartStatus> = ref('ready');

const startline = async (force: boolean, refresh: boolean) => {
    startStatus.value = 'preparing';

    if (!force) {
        const start_check: object[] = await invoke('start_check');
        if (start_check.length > 0) {
            const message = start_check.map((o) => {
                if ('MissingRemotePackage' in o) {
                    return `Package missing: ${o.MissingRemotePackage}`;
                } else if ('MissingLocalPackage' in o) {
                    return `Package missing: ${o.MissingLocalPackage}`;
                } else if ('MissingDependency' in o) {
                    return `Dependency missing: ${o.MissingDependency}`;
                } else if ('MissingTool' in o) {
                    return `Tool missing: ${o.MissingTool}`;
                } else {
                    return 'Unknown error';
                }
            });
            confirmDialog.require({
                message: message.join('\n'),
                header: 'Start check failed',
                acceptLabel: 'Run anyway',
                rejectLabel: 'Cancel',
                accept: () => {
                    startline(true, refresh);
                },
            });
            startStatus.value = 'ready';
            return;
        }
    }
    try {
        await invoke('save_current_profile');
        await invoke('startline', { refresh });
    } catch (_) {
        startStatus.value = 'ready';
    }
};

const kill = async () => {
    await invoke('kill');
};

const disabledTooltip = computed(() => {
    if (prf.current?.data.sgt.target.length === 0) {
        return 'The game path must be specified';
    }
    if (prf.current?.data.sgt.amfs.length === 0) {
        return 'The amfs path must be specified';
    }
    if (
        prf.current?.data.sgt.hook === null ||
        prf.current?.data.sgt.hook === undefined
    ) {
        return 'A segatools hook package is necessary';
    }
    return null;
});

listen('launch-start', () => {
    startStatus.value = 'running';
    getCurrentWindow().minimize();
});

listen('launch-end', () => {
    startStatus.value = 'ready';
    getCurrentWindow().unminimize();
    getCurrentWindow().setFocus();
});

const menuItems = [
    {
        label: 'Refresh and start',
        icon: 'pi pi-sync',
        command: async () => await startline(false, true),
    },
    {
        label: 'Start unchecked',
        icon: 'pi pi-exclamation-circle',
        command: async () => await startline(true, false),
    },
];
const menu = ref();

const showContextMenu = (event: Event) => {
    event.preventDefault();
    menu.value.show(event);
};
</script>

<template>
    <ContextMenu ref="menu" :model="menuItems" />
    <Button
        v-if="startStatus === 'ready'"
        v-tooltip="disabledTooltip"
        :disabled="disabledTooltip !== null"
        icon="pi pi-play"
        label="START"
        aria-label="start"
        size="small"
        class="m-2.5"
        @click="startline(false, false)"
        @contextmenu="showContextMenu"
    />
    <Button
        v-else-if="startStatus === 'preparing'"
        disabled
        icon="pi pi-spin pi-spinner"
        label="START"
        aria-label="start"
        size="small"
        class="m-2.5"
    />
    <Button
        v-else
        :disabled="false"
        icon="pi pi-ban"
        label="STOP"
        aria-label="stop"
        size="small"
        class="m-2.5"
        @click="kill()"
    />
</template>
