<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import { computed, ref } from 'vue';
import { useExpenseForm }  from '../../composables/use-expense-form';
import { useExpenseDraft } from '../../composables/use-expense-draft';
import { useExpenseItems } from '../../composables/use-expense-items';
import { COMMENT_MAX_LENGTH } from '../../constants/expense.constants';
import { useToggle } from 'src/modules/shared/composables/use-toggle';
import ExpenseList from './expense-list.vue';
import ExpenseForm from './expense-form.vue';
import { 
    buildExpenseTypeOptions,
    computeExpenseTotals,
    makeExpenseRules,
    buildExpenseSavePayload
} from '../../utils/expense.util';
import { EXPENSE_TYPE }     from '../../types/expense.types';
import { ExpensesValidationError } from '../../types/expense-validation.interface';
import type { TimesheetExpense } from '../../types/expense.interfaces';

/* eslint-disable */

const { t , locale } = useI18n();
const rules = makeExpenseRules(t, COMMENT_MAX_LENGTH);

//------------------ props ------------------
const props = defineProps<{
    pay_period_no: number;
    pay_year:      number;
    email:         string;
    is_approved?:  boolean;
    initial_expenses?: TimesheetExpense[];
}>();

//------------------ emits ------------------
const emit = defineEmits<{
    (e:'close'): void;
    (e: 'save', payload: {
        pay_period_no: number;
        pay_year:      number;
        email:         string;
        expenses: TimesheetExpense[];
    }): void;
    (e: 'error', err: ExpensesValidationError): void;
}>();

//------------------ q-select mapper ------------------
const type_options = computed(()=> {
    void locale.value;
    return buildExpenseTypeOptions(EXPENSE_TYPE, t);
})

//------------------ refs and computed ------------------
const files               = ref<File[] | null>(null);
const is_readonly = computed(()=> !!props.is_approved);

const { state: is_open_date_picker } = useToggle();
const { draft, setType, reset, showAmount } = useExpenseDraft();
const { validateAnd } = useExpenseForm();
const { items, addFromDraft, removeAt, validateAll, payload } = useExpenseItems({
    initial_expenses: props.initial_expenses,
    draft,
    is_approved: is_readonly,
});
const totals = computed(()=> computeExpenseTotals(items.value));

//------------------ actions ------------------
const onSave = () => {
    try {
        validateAll();
        reset();
        emit('save', buildExpenseSavePayload({
            pay_period_no: props.pay_period_no,
            pay_year:      props.pay_year,
            email:         props.email,
            expenses:      payload(),
        }));

    } catch(err: any) {
        const e = err instanceof ExpensesValidationError
            ? err
            : new ExpensesValidationError({
                status_code: 400,
                message: String(err?.message || err)
            });
        emit('error', e);
    }
};

const onFormSubmit = async () => {
    try {
        await validateAnd(async () => {
            addFromDraft();
            reset();
        });
    } catch (err: any) {
        const e = err instanceof ExpensesValidationError
            ? err
            : new ExpensesValidationError({
                status_code: 400,
                message: String(err?.message || err)
            });
        emit('error', e);
    }
};

const onClose = () => emit('close');

</script>

<template>
    <div>
        <!-- header (title with totals)-->
        <q-item class="row justify-between">
            <q-item-label header class="text-h6 col-auto"> 
                {{ $t('timesheet.expense.title') }}
            </q-item-label>
        <q-item-section class="items-center col-auto">
            <q-badge lines="1" class="q-pa-sm q-px-md" :label="$t('timesheet.expense.total_amount')  + ': ' + totals.amount.toFixed(2)"/>
            <q-separator spaced/>
            <q-badge lines="2" class="q-pa-sm q-px-md" :label="$t('timesheet.expense.total_mileage') + ': ' + totals.mileage.toFixed(1)"/>
        </q-item-section>
        </q-item>
        <ExpenseList
            :items="items"
            :is_readonly="is_readonly"
            @remove="removeAt"
        />
        <ExpenseForm
            v-model:draft="draft"
            v-model:files="files"
            v-model:date-picker-open="is_open_date_picker"
            :type_options="type_options"
            :show_amount="showAmount"
            :is_readonly="is_readonly"
            :rules="rules"
            :comment_max_length="COMMENT_MAX_LENGTH"
            :set-type="setType"
            @submit="onFormSubmit"
        />
        
        <q-separator spaced/>
        
        <div class="row col-auto justify-end">
            <!-- close btn -->
            <q-btn
                flat
                class="q-mr-sm"
                color="primary"
                :label="$t('timesheet.cancel_button')"
                @click="onClose"
            />
            <!-- save btn -->
            <q-btn
                color="primary"
                unelevated
                push
                :disable="is_readonly || items.length === 0"
                :label="$t('timesheet.save_button')"
                @click="onSave"
            />
        </div>
    </div>
</template>