<script
    setup
    lang="ts"
>
    import ShiftList from 'src/modules/timesheets/components/shift-list.vue';
    import ShiftListScrollable from 'src/modules/timesheets/components/shift-list-scrollable.vue';
    import LoadingOverlay from 'src/modules/shared/components/loading-overlay.vue';
    import ExpenseDialog from 'src/modules/timesheets/components/expense-dialog.vue';
    import PayPeriodNavigator from 'src/modules/shared/components/pay-period-navigator.vue';
    import TimesheetErrorWidget from 'src/modules/timesheets/components/timesheet-error-widget.vue';
    import ShiftListWeeklyOverview from 'src/modules/timesheets/components/shift-list-weekly-overview.vue';
    import ShiftListWeeklyOverviewMobile from 'src/modules/timesheets/components/mobile/shift-list-weekly-overview-mobile.vue';
    import UnsavedChangesDialog from 'src/modules/timesheets/components/unsaved-changes-dialog.vue';

    import { date, Notify } from 'quasar';
    import { useI18n } from 'vue-i18n';
    import { useRouter } from 'vue-router';
    import { computed, onMounted, provide } from 'vue';
    import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api';
    import { useTimesheetApi } from 'src/modules/timesheets/composables/use-timesheet-api';
    import { useExpensesStore } from 'src/stores/expense-store';
    import { useTimesheetStore } from 'src/stores/timesheet-store';
import { RouteNames } from 'src/router/router-constants';

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

    const { mode = 'normal', employeeEmail } = defineProps<{
        mode?: 'approval' | 'normal';
        employeeEmail?: string | undefined;
    }>();

    const { t } = useI18n();
    const router = useRouter();
    const expenseStore = useExpensesStore();
    const timesheetStore = useTimesheetStore();
    const timesheetApi = useTimesheetApi();
    const shiftApi = useShiftApi();

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

    const hasShiftErrors = computed(() => timesheetStore.all_current_shifts.filter(shift => shift.has_error === true).length > 0);
    const isTimesheetsApproved = computed(() => timesheetStore.timesheets.every(timesheet => timesheet.is_approved));

    const weeklyHours = computed(() => timesheetStore.timesheets.map(timesheet => 
        Object.values(timesheet.weekly_hours).reduce((sum, hoursPerType) => sum += hoursPerType, 0) - timesheet.weekly_hours.sick
    ));
    const totalHours = computed(() => timesheetStore.timesheets.reduce((sum, timesheet) =>
        sum += timesheet.weekly_hours.regular
        + timesheet.weekly_hours.evening
        + timesheet.weekly_hours.emergency
        + timesheet.weekly_hours.vacation
        + timesheet.weekly_hours.holiday
        + timesheet.weekly_hours.overtime,
        0 //initial value
    ));

    const totalExpenses = computed(() => timesheetStore.timesheets.reduce((sum, timesheet) =>
        sum + timesheet.weekly_expenses.expenses
        + timesheet.weekly_expenses.on_call
        + timesheet.weekly_expenses.per_diem,
        0 //initial value
    ));

    // =================== methods ==========================

    provide('employeeEmail', employeeEmail);
    provide('mode', mode);

    const onClickSaveTimesheets = async () => {
        if (mode === 'normal') {
            await shiftApi.saveShiftChanges();
            Notify.create({
                message: t('timesheet.save_successful'),
                color: 'accent',
            });
        } else {
            await shiftApi.saveShiftChanges(timesheetStore.current_pay_period_overview?.email);
        }
    }

    const onClickLeave = async () => {
        timesheetStore.isShowingUnsavedWarning = false;
        timesheetStore.timesheets = [];
        timesheetStore.initial_timesheets = [];
        await router.push({ name: timesheetStore.nextPageNameAfterUnsaveWarning ?? RouteNames.DASHBOARD});
    }

    const onClickSaveBeforeLeaving = async () => {
        if (mode === 'approval') return;

        timesheetStore.isShowingUnsavedWarning = false;
        await onClickSaveTimesheets();
        await onClickLeave();
    }

    onMounted(async () => {
        if (mode === 'normal')
            await timesheetApi.getTimesheetsByDate(date.formatDate(new Date(), 'YYYY-MM-DD'));
    });
</script>

<template>
    <div
        class="column items-center full-height"
        :class="mode === 'normal' ? 'relative-position' : ' no-wrap'"
    >
        <LoadingOverlay v-model="timesheetStore.is_loading" />

        <!-- label for approval mode to delimit that this is the timesheet -->
        <div
            v-if="mode === 'approval'"
            class="col-auto row full-width q-px-xl"
        >
            <span class="col-auto text-uppercase text-bold text-h5">
                {{ $t('timesheet.page_header') }}
            </span>

            <q-space />
        </div>


        <!-- weekly overview -->
        <div class="col-auto row q-px-lg full-width">
            <!-- supervisor weekly overview -->
            <div
                v-if="!$q.platform.is.mobile"
                class="col-xs-6 col-md-4 col-xl-3 q-pa-md"
            >
                <ShiftListWeeklyOverview
                    mode="total-hours"
                    :timesheet-mode="mode"
                    :weekly-hours="weeklyHours"
                    :total-hours="totalHours"
                    :total-expenses="totalExpenses"
                />
            </div>

            <q-space v-if="!$q.platform.is.mobile" />

            <!-- employee weekly overview -->
            <div
                v-if="!$q.platform.is.mobile"
                class="col-xs-6 col-md-4 col-xl-3 q-pa-md"
            >
                <ShiftListWeeklyOverview
                    mode="off-hours"
                    :timesheet-mode="mode"
                />
            </div>
        </div>

        <!-- top menu -->
        <div
            v-if="mode === 'normal'"
            class="col-auto row items-center full-width"
            :class="$q.platform.is.mobile && ($q.screen.width < $q.screen.height) ? 'justify-between q-px-md' : 'q-pb-sm q-px-xl'"
        >
            <!-- navigation btn -->
            <PayPeriodNavigator
                class="col-auto"
                @date-selected="timesheetApi.getTimesheetsByDate"
                @pressed-previous-button="timesheetApi.getTimesheetsByCurrentPayPeriod"
                @pressed-next-button="timesheetApi.getTimesheetsByCurrentPayPeriod"
            />

            <!-- mobile expenses button -->
            <div
                v-if="$q.screen.width < $q.screen.height && mode === 'normal'"
                class="col q-pl-lg"
            >
                <q-btn
                    push
                    rounded
                    color="accent"
                    icon="receipt_long"
                    class="full-width"
                    @click="expenseStore.open"
                />
            </div>

            <q-space v-if="$q.screen.width > $q.screen.height" />

            <!-- desktop expenses button -->
            <q-btn
                v-if="mode === 'normal' && $q.screen.width > $q.screen.height"
                push
                rounded
                color="accent"
                icon="receipt_long"
                :label="$t('timesheet.expense.open_btn')"
                @click="expenseStore.open"
            />

            <!-- desktop save timesheet changes button -->
            <q-btn
                v-if="!isTimesheetsApproved && $q.screen.width > $q.screen.height"
                push
                rounded
                :disable="timesheetStore.is_loading || hasShiftErrors || !timesheetStore.canSaveTimesheets"
                :color="timesheetStore.is_loading || hasShiftErrors || !timesheetStore.canSaveTimesheets ? 'grey-5' : 'accent'"
                icon="upload"
                :label="$t('shared.label.save')"
                :class="$q.platform.is.mobile && ($q.screen.width < $q.screen.height) ? 'full-width' : 'q-ml-md'"
                @click="onClickSaveTimesheets"
            />
        </div>

        <!-- error message widget for potential backend-provided errors -->
        <TimesheetErrorWidget class="col-auto" />

        <!-- mobile weekly overview widget -->
        <ShiftListWeeklyOverviewMobile class="col-auto" />

        <!-- standard scrollable shift list for user input -->
        <ShiftListScrollable
            v-if="mode === 'normal'"
            :mode="mode"
            :class="mode === 'normal' ? 'col' : 'col-auto'"
        />

        <!-- full shift list for timesheet approval details dialog -->
        <div
            v-else
            class="col-auto column"
            :class="$q.platform.is.mobile ? 'fit no-wrap' : 'full-width'"
            :style="$q.platform.is.mobile && $q.screen.width < $q.screen.height ? 'margin-bottom: 40px' : ''"
        >
            <!-- If no timesheets found -->
            <div
                v-if="timesheetStore.timesheets.length < 1 && !timesheetStore.is_loading"
                class="col-auto column flex-center fit q-py-lg"
                style="min-height: 20vh;"
            >
                <span class="text-uppercase text-weight-bolder text-center">{{ $t('shared.error.no_data_found')
                }}</span>
                <q-icon
                    name="las la-calendar"
                    color="accent"
                    size="10em"
                    class="absolute"
                    style="opacity: 0.2;"
                />
            </div>

            <!-- Else show timesheets -->
            <ShiftList
                v-else
                class="col-auto"
            />
        </div>

        <q-btn
            v-if="$q.platform.is.mobile && $q.screen.width < $q.screen.height"
            square
            :disable="timesheetStore.is_loading || hasShiftErrors || !timesheetStore.canSaveTimesheets"
            size="lg"
            color="accent"
            icon="upload"
            :label="$t('shared.label.save')"
            class="absolute-bottom shadow-up-10"
            style="height: 40px;"
            @click="onClickSaveTimesheets"
        />

        <ExpenseDialog
            :is-approved="isTimesheetsApproved"
            class="z-top"
        />

        <UnsavedChangesDialog
            @click-save-no="onClickLeave"
            @click-save-yes="onClickSaveBeforeLeaving"
        />
    </div>
</template>