import { computed, ref } from "vue";
import { defineStore } from "pinia";
import { useTimesheetStore } from "src/stores/timesheet-store";
import { default_expense, default_pay_period_expenses, type UpsertExpense, type Expense, type PayPeriodExpenses } from "src/modules/timesheets/models/expense.models";
import { timesheetService } from "src/modules/timesheets/services/timesheet-service";
import { ExpensesApiError, type GenericApiError } from "src/modules/timesheets/models/expense.validation";
import { computeExpenseTotals } from "src/modules/timesheets/utils/expense.util";
import type { UpsertAction } from "src/modules/timesheets/models/shift.models";



export const useExpensesStore = defineStore('expenses', () => {
    const timesheet_store = useTimesheetStore();
    const is_open = ref(false);
    const is_loading = ref(false);
    const mode = ref<UpsertAction>('create');
    const pay_period_expenses = ref<PayPeriodExpenses>(default_pay_period_expenses);
    const pay_period_expenses_totals = computed(() => computeExpenseTotals(pay_period_expenses.value.expenses))
    const current_expense = ref<Expense>(default_expense);
    const initial_expense = ref<Expense>(default_expense);
    const error = ref<string | null>(null);

    // const setErrorFrom = (err: unknown) => {
    //     const e = err as any;
    //     error.value = e?.message || 'Unknown error';
    // };

    const open = async (employee_email: string): Promise<void> => {
        is_open.value = true;
        is_loading.value = true;
        error.value = null;
        current_expense.value = default_expense;
        initial_expense.value = default_expense;

        await getPayPeriodExpensesByEmployeeEmail(employee_email);
        is_loading.value = false;
    }

    const close = () => {
        error.value = null;
        is_open.value = false;
    };

    const getPayPeriodExpensesByEmployeeEmail = async (employee_email: string): Promise<void> => {
        is_loading.value = true;
        error.value = null;

        try {
            const expenses = await timesheetService.getExpensesByPayPeriodAndEmployeeEmail(
                encodeURIComponent(employee_email),
                encodeURIComponent(timesheet_store.pay_period.pay_year),
                encodeURIComponent(timesheet_store.pay_period.pay_period_no),
            );
            pay_period_expenses.value = expenses;
        } catch (err: unknown) {
            if (typeof err === 'object') {
                const error = err as GenericApiError;
                const status_code: number = error.status_code ?? 500;
                // const data = error.context ?? '';
                // error.value = data.message || data.error || err.message;
                
                throw new ExpensesApiError({
                    status_code,
                    // error_code: data.error_code,
                    // message: data.message || data.error || err.message,
                    // context: data.context,
                });
            }

        } finally {
            is_loading.value = false;
        }
    };

    const upsertOrDeleteExpensesByEmployeeEmail = async (employee_email: string, date: string, expense: UpsertExpense): Promise<void> => {
        is_loading.value = true;
        error.value = null;

        try {
            const updated_expenses = await timesheetService.upsertOrDeleteExpensesByPayPeriodAndEmployeeEmail(
                encodeURIComponent(employee_email),
                encodeURIComponent(date),
                expense,
            );
            console.log('updated expenses received: ', updated_expenses)
            pay_period_expenses.value.expenses = updated_expenses;
        } catch (err) {
            // setErrorFrom(err);
            console.log('error doing some expense thing: ', err)
        } finally {
            is_loading.value = false;
        }
    };

    return {
        is_open,
        is_loading,
        mode,
        pay_period_expenses,
        pay_period_expenses_totals,
        current_expense,
        initial_expense,
        error,
        open,
        getPayPeriodExpensesByEmployeeEmail,
        upsertOrDeleteExpensesByEmployeeEmail,
        close,
    };
});