<script setup lang="ts">
import { computed, ref } from 'vue';
import InputText from 'primevue/inputtext';
import { fromKeycode, toKeycode } from '../keyboard';
import { usePrfStore } from '../stores';
import { OngekiButtons } from '../types';
import { useI18n } from 'vue-i18n';

const { t } = useI18n();

const prf = usePrfStore();

const hasClickedM1Once = ref(false);

const handleKey = (
    button: string | undefined,
    event: KeyboardEvent,
    index?: number
) => {
    event.preventDefault();

    let keycode = toKeycode(event.code);

    if (keycode !== null && button !== undefined) {
        const data = prf.current!.data.keyboard!.data as any;

        if (event.getModifierState('NumLock') === false) {
            switch (event.code) {
                case 'NumpadDecimal':
                    keycode = toKeycode('Delete');
                    break;
                case 'Numpad0':
                    keycode = toKeycode('Insert');
                    break;
                case 'Numpad1':
                    keycode = toKeycode('End');
                    break;
                case 'Numpad2':
                    keycode = toKeycode('ArrowDown');
                    break;
                case 'Numpad3':
                    keycode = toKeycode('PageDown');
                    break;
                case 'Numpad4':
                    keycode = toKeycode('ArrowLeft');
                    break;
                case 'Numpad5':
                    keycode = toKeycode('Clear');
                    break;
                case 'Numpad6':
                    keycode = toKeycode('ArrowRight');
                    break;
                case 'Numpad7':
                    keycode = toKeycode('Home');
                    break;
                case 'Numpad8':
                    keycode = toKeycode('ArrowUp');
                    break;
                case 'Numpad9':
                    keycode = toKeycode('PageUp');
                    break;
                default:
                    break;
            }
        }

        if (event.code === 'Escape') {
            keycode = 0;
        }

        if (index !== undefined) {
            data[button][index] = keycode;
        } else {
            data[button] = keycode;
        }
    }
};

const handleMouse = (
    button: string | undefined,
    event: MouseEvent,
    index?: number
) => {
    if (button === undefined || button == 'use_mouse') {
        return;
    }

    if (event.button === 0) {
        if (hasClickedM1Once.value === false) {
            hasClickedM1Once.value = true;
            return;
        }
    } else {
        event.preventDefault();
    }

    let keycode;
    switch (event.button) {
        case 0:
            keycode = 1;
            break;
        case 1:
            keycode = 4;
            break;
        case 2:
            keycode = 2;
            break;
        case 3:
            keycode = 5;
            break;
        case 4:
            keycode = 6;
            break;
        default:
            break;
    }
    if (keycode !== undefined) {
        const data = prf.current!.data.keyboard!.data as any;

        if (index !== undefined) {
            data[button][index] = keycode;
        } else {
            data[button] = keycode;
        }
    }
};

const getKey = (key: keyof OngekiButtons, index?: number): any =>
    computed(() => {
        const data = prf.current!.data.keyboard?.data as any;
        const keycode =
            index === undefined
                ? (data[key] as number | undefined)
                : (data[key]?.[index] as number | undefined);
        return keycode && fromKeycode(keycode) ? fromKeycode(keycode) : '–';
    });

const props = defineProps({
    small: Boolean,
    tall: Boolean,
    tooltip: String,
    button: String,
    color: String,
    index: Number,
});

const modelValue = computed(() => {
    return getKey(props.button as keyof OngekiButtons, props.index).value;
});

const fontSize = computed(() => {
    if (!props.small) {
        return '1rem';
    }
    const len = modelValue.value.length;
    if (len < 5) {
        return '1rem';
    }
    if (len < 7) {
        return '0.75rem';
    }
    return '0.5rem';
});
</script>

<template>
    <InputText
        :style="{
            width: small ? '2.8rem' : '5rem',
            height:
                small && tall
                    ? '5rem'
                    : small
                      ? '2.8rem'
                      : tall
                        ? '10rem'
                        : '5rem',
            fontSize,
            backgroundColor: color,
        }"
        unstyled
        class="text-center buttoninputtext"
        v-tooltip="
            tooltip
                ? `${tooltip}: ${modelValue} ${tooltip.startsWith('ir') ? `\n${t('cfg.keyboard.irTooltip')}` : ''}`
                : undefined
        "
        @contextmenu.prevent="() => {}"
        @keydown="(ev: KeyboardEvent) => handleKey(button, ev, index)"
        @mousedown="
            (ev: MouseEvent) =>
                handleMouse(button as keyof OngekiButtons, ev, index)
        "
        @focusout="() => (hasClickedM1Once = false)"
        :model-value="modelValue"
    />
</template>

<style scoped lang="css">
.buttoninputtext {
    border-radius: 6px;
    border: 1px solid rgba(200, 200, 200, 0.3);
    overflow: scroll !important;
    text-align: center !important;
}
</style>
