<script
    setup
    lang="ts"
>
    import TargoInput from 'src/modules/shared/components/targo-input.vue';

    import { useI18n } from 'vue-i18n';
    import { computed, onMounted, ref } from 'vue';
    import { useExpensesStore } from 'src/stores/expense-store';
    import { useTimesheetStore } from 'src/stores/timesheet-store';
    import { useExpensesApi } from 'src/modules/timesheets/composables/use-expense-api';
    import { getExpenseIcon, useExpenseRules } from 'src/modules/timesheets/utils/expense.util';
    import { Expense, type ExpenseOption, TYPES_WITH_AMOUNT_ONLY } from 'src/modules/timesheets/models/expense.models';

    // ================= state ======================

    const COMMENT_MAX_LENGTH = 280;

    const expense = defineModel<Expense>({ default: new Expense(new Date().toISOString().slice(0, 10)) })
    const file = defineModel<File>('file');
    const { email } = defineProps<{
        email?: string | undefined;
        mode?: 'normal' | 'approval';
    }>();
    const emit = defineEmits<{
        'clickSave': [void];
    }>();

    const { t } = useI18n();
    const timesheetStore = useTimesheetStore();
    const expenseStore = useExpensesStore();
    const expensesApi = useExpensesApi();
    const isNavigatorOpen = ref(false);
    const rules = useExpenseRules(t);


    const expenseOptions: ExpenseOption[] = [
        { label: t('timesheet.expense.types.EXPENSES'), value: 'EXPENSES', icon: getExpenseIcon('EXPENSES') },
        { label: t('timesheet.expense.types.PER_DIEM'), value: 'PER_DIEM', icon: getExpenseIcon('PER_DIEM') },
        { label: t('timesheet.expense.types.MILEAGE'), value: 'MILEAGE', icon: getExpenseIcon('MILEAGE') },
        { label: t('timesheet.expense.types.ON_CALL'), value: 'ON_CALL', icon: getExpenseIcon('ON_CALL') },
    ]
    const expenseSelected = ref<ExpenseOption | undefined>();

    // ================== computed ===================

    const period_start_date = computed(() => timesheetStore.pay_period?.period_start.replaceAll('-', '/') ?? '');
    const period_end_date = computed(() => timesheetStore.pay_period?.period_end.replaceAll('-', '/') ?? '');
    const isSaveDisabled = computed(() =>
        JSON.stringify(expenseStore.current_expense) === JSON.stringify(expenseStore.initial_expense)
    );

    // ==================== method =======================

    const openDatePicker = () => {
        isNavigatorOpen.value = true;
        if (expenseStore.current_expense.date === undefined) {
            expenseStore.current_expense.date = timesheetStore.pay_period?.period_start ?? '';
        }
    };

    const closeDatePicker = (date: string) => {
        isNavigatorOpen.value = false;
        expenseStore.current_expense.date = date;
    }

    const requestExpenseCreationOrUpdate = async () => {
        const success = await expensesApi.upsertExpense(expenseStore.current_expense, email, file.value);

        if (success) {
            expenseStore.is_showing_create_form = false;
            emit('clickSave');
        }
    };

    onMounted(() => {
        if (expense.value)
            expenseSelected.value = expenseOptions.find(expense_option => expense_option.value === expense.value.type);
        else
            expenseSelected.value = expenseOptions[0];
    })
</script>

<template>
    <div
        v-if="!expenseStore.current_expense.is_approved"
        class="full-width q-mt-md q-px-md"
    >
        <q-form
            flat
            @submit.prevent="requestExpenseCreationOrUpdate"
        >
            <div class="column rounded-5 q-pb-sm">
                <div class="row">
                    <!-- date selection input -->
                    <div class="row col items-center q-pl-sm">
                        <q-btn
                            push
                            dense
                            icon="event"
                            color="accent"
                            class="col-auto"
                            @click="openDatePicker"
                        />

                        <q-dialog
                            v-model="isNavigatorOpen"
                            transition-show="jump-right"
                            transition-hide="jump-right"
                            class="z-top"
                        >
                            <q-date
                                v-model="expenseStore.current_expense.date"
                                mask="YYYY-MM-DD"
                                event-color="accent"
                                :options="date => date >= period_start_date && date <= period_end_date"
                                @update:model-value="closeDatePicker"
                            />
                        </q-dialog>

                        <TargoInput
                            v-model="expenseStore.current_expense.date"
                            no-top-padding
                            :label="$t('timesheet.expense.date')"
                            background-color="bg-dark"
                            class="col"
                        />
                    </div>

                    <!-- expenses type selection -->
                    <div class="col">
                        <q-select
                            v-model="expenseSelected"
                            dense
                            borderless
                            color="accent"
                            label-color="white"
                            stack-label
                            label-slot
                            :options="expenseOptions"
                            hide-dropdown-icon
                            lazy-rules
                            no-error-icon
                            hide-bottom-space
                            options-selected-class="text-white text-bold bg-accent"
                            class="q-px-md rounded-5 inset-shadow"
                            :class="$q.dark.isActive ? 'bg-primary' : 'bg-dark'"
                            popup-content-class="text-uppercase text-weight-medium rounded-5 shadow-12  z-top"
                            popup-content-style="border: 1px solid var(--q-primary);"
                            menu-anchor="bottom middle"
                            menu-self="top middle"
                            :menu-offset="[0, 5]"
                            :style="`border: 1px solid var(${$q.dark.isActive ? '--q-secondary' : '--q-primary'});`"
                            :rules="[rules.typeRequired]"
                            @update:model-value="option => expenseStore.current_expense.type = option.value"
                        >
                            <template #label>
                                <span
                                    class="text-weight-medium text-uppercase q-px-sm no-pointer-events"
                                    :class="$q.dark.isActive ? 'bg-secondary' : 'bg-primary'"
                                >
                                    {{ $t('timesheet.expense.type') }}
                                </span>
                            </template>

                            <template #selected-item="scope">
                                <div
                                    class="row items-center text-weight-bold q-ma-none q-pa-none no-wrap ellipsis full-width"
                                    :tabindex="scope.tabindex"
                                >
                                    <q-icon
                                        :name="scope.opt.icon"
                                        size="xs"
                                        class="col-auto q-mx-xs"
                                    />
                                    <span
                                        style="line-height: 1em;"
                                        class="col-auto ellipsis text-uppercase"
                                    >{{ scope.opt.label }}</span>
                                </div>
                            </template>
                        </q-select>
                    </div>

                    <!-- amount input -->
                    <div class="col">
                        <TargoInput
                            v-if="TYPES_WITH_AMOUNT_ONLY.includes(expenseStore.current_expense?.type ?? 'EXPENSES')"
                            v-model.number="expenseStore.current_expense.amount"
                            no-top-padding
                            background-color="bg-dark"
                            type="number"
                            input-class="text-right"
                            append-content=" $"
                            :label="$t('timesheet.expense.amount')"
                        />

                        <TargoInput
                            v-else
                            v-model.number="expenseStore.current_expense.mileage"
                            no-top-padding
                            background-color="bg-dark"
                            type="number"
                            input-class="text-right"
                            append-content=" km"
                            :label="$t('timesheet.expense.mileage')"
                        />
                    </div>
                </div>

                <div class="row q-pt-md">
                    <!-- employee comment input -->
                    <div class="col">
                        <TargoInput
                            v-model="expenseStore.current_expense.comment"
                            no-top-padding
                            background-color="bg-dark"
                            :max-length="COMMENT_MAX_LENGTH"
                            :label="$t('timesheet.expense.employee_comment')"
                        />
                    </div>

                    <div
                        v-if="mode === 'approval'"
                        class="col"
                    >
                        <TargoInput
                            v-model="expenseStore.current_expense.supervisor_comment"
                            no-top-padding
                            background-color="bg-dark"
                            :max-length="COMMENT_MAX_LENGTH"
                            :label="$t('timesheet.expense.supervisor_comment')"
                        />
                    </div>

                    <!-- import attach file section -->
                    <div class="col-3 q-px-sm">
                        <q-file
                            v-model="file"
                            dense
                            borderless
                            color="accent"
                            label-color="white"
                            stack-label
                            label-slot
                            type="file"
                            accept="image/*"
                            class="q-px-md rounded-5 inset-shadow"
                            :class="$q.dark.isActive ? 'bg-primary' : 'bg-dark'"
                            :style="`border: 1px solid var(${$q.dark.isActive ? '--q-secondary' : '--q-primary'});`"
                        >
                            <template #append>
                                <q-icon
                                    name="attach_file"
                                    size="sm"
                                    color="accent"
                                />
                            </template>

                            <template #label>
                                <span
                                    class="text-weight-medium text-uppercase q-px-sm no-pointer-events"
                                    :class="$q.dark.isActive ? 'bg-secondary' : 'bg-primary'"
                                >
                                    {{ $t('timesheet.expense.hints.attach_file') }}
                                </span>
                            </template>
                        </q-file>
                    </div>
                </div>
            </div>

            <div class="col row full-width items-center">
                <q-space />

                <q-btn
                    push
                    :disable="isSaveDisabled"
                    :color="isSaveDisabled ? 'grey-5' : 'accent'"
                    :icon="expenseStore.mode === 'update' ? 'save' : 'upload'"
                    :label="expenseStore.mode === 'update' ? $t('shared.label.update') : $t('shared.label.add')"
                    class="q-px-sm "
                    :class="expenseStore.mode === 'create' ? 'q-mr-lg q-mb-md' : 'q-mb-sm q-ml-lg'"
                    type="submit"
                />
            </div>
        </q-form>
    </div>
</template>

<style
    scoped
    lang="css"
>
    :deep(.q-field--dense.q-field--float .q-field__label) {
        transform: translate(-17px, -60%) scale(0.75) !important;
        border-radius: 10px 10px 10px 0px;
    }
</style>