<script
    setup
    lang="ts"
>
    /* eslint-disable */
    import OverviewListItem from 'src/modules/timesheet-approval/components/overview-list-item.vue';
    import LoadingOverlay from 'src/modules/shared/components/loading-overlay.vue';
    import OverviewListTop from 'src/modules/timesheet-approval/components/overview-list-top.vue';
    import OverviewListTopMobile from 'src/modules/timesheet-approval/components/mobile/overview-list-top-mobile.vue';

    import { useQuasar } from 'quasar';
    import { computed, ref } from 'vue';
    import { useAuthStore } from 'src/stores/auth-store';
    import { useTimesheetStore } from 'src/stores/timesheet-store';
    import { useTimesheetApprovalApi } from 'src/modules/timesheet-approval/composables/use-timesheet-approval-api';
    import { type OverviewColumns, pay_period_overview_columns, PayPeriodOverviewFilters, type TimesheetApprovalOverview } from 'src/modules/timesheet-approval/models/timesheet-overview.models';
    import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-utils';
    import { useUiStore } from 'src/stores/ui-store';

    // ========== constants ========================================

    const WARNING_COLUMNS: OverviewColumns[] = ['EVENING', 'HOLIDAY', 'VACATION', 'SICK']
    const NEGATIVE_COLUMNS: OverviewColumns[] = ['OVERTIME', 'EMERGENCY']
    const TIME_COLUMNS: OverviewColumns[] = ['REGULAR', 'EVENING', 'EMERGENCY', 'OVERTIME', 'HOLIDAY', 'VACATION', 'SICK'];
    const VISIBLE_COLUMNS = ref<OverviewColumns[]>([
        'employee_first_name',
        'REGULAR',
        'EVENING',
        'EMERGENCY',
        'OVERTIME',
        'HOLIDAY',
        'VACATION',
        'expenses',
        'mileage',
        'weekly_hours_1',
        'weekly_hours_2',
        'total_hours',
        'is_approved',
    ]);

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

    const { maxHeight } = defineProps<{
        maxHeight: number;
    }>();

    const q = useQuasar();
    const uiStore = useUiStore();
    const auth_store = useAuthStore();
    const timesheet_store = useTimesheetStore();
    const timesheet_approval_api = useTimesheetApprovalApi();

    const overview_filters = ref<PayPeriodOverviewFilters>({
        is_showing_inactive: false,
        is_showing_team_only: true,
        supervisors: [],
        name_search_string: '',
    });

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

    const isGridMode = computed(() => q.platform.is.mobile ? true :
        uiStore.user_preferences.is_timesheet_approval_grid
    );

    const overview_rows = computed(() =>
        timesheet_store.pay_period_overviews.filter(overview => overview)
    );

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

    const onClickedDetails = async (row: TimesheetApprovalOverview) => {
        timesheet_store.current_pay_period_overview = row;
        await timesheet_store.getTimesheetsByOptionalEmployeeEmail(row.email);

        timesheet_store.is_details_dialog_open = true;
    };

    const onClickApproveAll = async (email: string, is_approved: boolean) => {
        await timesheet_approval_api.toggleTimesheetsApprovalByEmployeeEmail(email, is_approved);
    }

    const filterEmployeeRows = (rows: readonly TimesheetApprovalOverview[], terms: PayPeriodOverviewFilters): TimesheetApprovalOverview[] => {
        let result = [...rows];

        if (!terms.is_showing_inactive) {
            result = result.filter(row => row.is_active);
        }

        if (terms.is_showing_team_only) {
            result = result.filter(row => row.supervisor !== null && row.supervisor.email === (auth_store.user ? auth_store.user.email : ''));
        }

        if (terms.name_search_string.length > 0) {
            const search_words = terms.name_search_string.trim().split(' ');
            search_words.map(word => result = result.filter(row =>
                row.employee_first_name.toLowerCase().includes(word.toLowerCase() ?? '') || row.employee_last_name.toLowerCase().includes(word ?? '')
            ));
        }

        return result;
    };

    const getListViewTimeCss = (column_name: OverviewColumns, value: number): { classes: string, style: string } => {
        if (WARNING_COLUMNS.includes(column_name) && value > 0)
            return { classes: 'bg-warning text-white text-bold rounded-5', style: '' };

        if (NEGATIVE_COLUMNS.includes(column_name) && value > 0)
            return { classes: 'bg-negative text-white text-bold rounded-5', style: '' };

        return { classes: '', style: '' }
    }
</script>

<template>
    <div class="full-width">
        <LoadingOverlay v-model="timesheet_store.is_loading" />
        <q-table
            dense
            row-key="email"
            color="accent"
            separator="none"
            hide-pagination
            :rows="overview_rows"
            :columns="pay_period_overview_columns"
            :table-colspan="pay_period_overview_columns.length"
            :visible-columns="VISIBLE_COLUMNS"
            :grid="isGridMode"
            :pagination="{ sortBy: 'is_active' }"
            :filter="overview_filters"
            :filter-method="filterEmployeeRows"
            :rows-per-page-options="[0]"
            class="bg-transparent"
            :class="uiStore.user_preferences.is_timesheet_approval_grid ? '' : 'sticky-header-table sticky-first-column-table sticky-last-column-table no-shadow q-pb-sm'"
            card-container-class="justify-center"
            table-class="q-pa-none q-mx-md rounded-10 bg-dark shadow-15"
            :no-data-label="$t('shared.error.no_data_found')"
            :no-results-label="$t('shared.error.no_search_results')"
            :loading-label="$t('shared.label.loading')"
            table-header-style="min-width: 80xp; max-width: 80px;"
            :style="overview_rows.length > 0 ? `max-height: ${maxHeight}px;` : ''"
            :table-style="{ tableLayout: 'fixed' }"
            @row-click="(_evt, row: TimesheetApprovalOverview) => onClickedDetails(row)"
        >
            <template #top>
                <OverviewListTopMobile
                    v-if="$q.platform.is.mobile"
                    v-model:filters="overview_filters"
                    v-model:visible-columns="VISIBLE_COLUMNS"
                />

                <OverviewListTop
                    v-else
                    v-model:filters="overview_filters"
                    v-model:visible-columns="VISIBLE_COLUMNS"
                />
            </template>

            <template #header="props">
                <q-tr
                    :props="props"
                    class="bg-primary"
                >
                    <q-th
                        v-for="col in props.cols"
                        :key="col.name"
                        :props="props"
                    >
                        <span class="text-uppercase text-weight-bolder text-white">
                            {{ $t(col.label) }}
                        </span>

                        <span
                            v-if="col.name.includes('weekly_hours')"
                            class="q-ml-sm text-uppercase text-weight-bolder text-white"
                        >
                            {{ col.name.slice(-1,) }}
                        </span>
                    </q-th>
                </q-tr>
            </template>

            <template #body-cell="props">
                <q-td
                    :props="props"
                    :class="props.rowIndex % 2 === 0 ? ($q.dark.isActive ? 'bg-primary' : 'bg-secondary') : ''"
                >
                    <transition
                        appear
                        enter-active-class="animated fadeInUp"
                        leave-active-class="animated fadeOutDown"
                        mode="out-in"
                    >
                        <div
                            :key="props.rowIndex + (timesheet_store.pay_period?.pay_period_no ?? 0)"
                            class="rounded-5"
                            :style="`animation-delay: ${props.rowIndex / 15}s; opacity: ${props.row.is_active ? '1' : '0.5'};`"
                        >
                            <!-- button to toggle approval status -->
                            <transition
                                v-if="props.col.name === 'is_approved'"
                                enter-active-class="animated swing"
                                mode="out-in"
                            >
                                <q-btn
                                    :key="props.row.is_approved"
                                    flat
                                    dense
                                    :icon="props.value ? 'lock' : 'lock_open'"
                                    :color="props.value ? 'white' : 'grey-5'"
                                    class="rounded-5 "
                                    :class="props.value ? (props.row.is_active ? 'bg-accent' : 'bg-negative') : ''"
                                    @click.stop="onClickApproveAll(props.row.email, !props.row.is_approved)"
                                />
                            </transition>

                            <!-- display full employee name with large first name and smaller last name -->
                            <div v-else-if="props.col.name === 'employee_first_name'">
                                <span
                                    class="text-h5 text-uppercase q-mr-xs"
                                    :class="props.row.is_active ? 'text-accent' : 'text-negative'"
                                >
                                    {{ props.value }}
                                </span>
                                <span class="text-uppercase text-weight-light">
                                    {{ props.row.employee_last_name }}
                                </span>
                            </div>

                            <!-- display weekly total hours (regular, vacation, holiday, emergency, evening) -->
                            <div
                                v-else-if="props.col.name.includes('weekly_hours')"
                                class="q-px-xs"
                            >
                                <span>
                                    {{
                                        getHoursMinutesStringFromHoursFloat((props.value[Number(props.col.name.slice(-1,)) -
                                            1]) ?? 0) }}
                                </span>
                            </div>

                            <!-- display total worked hours (regular, vacation, holiday, emergency, evening) -->
                            <div
                                v-else-if="props.col.name === 'total_hours'"
                                class="q-px-xs"
                            >
                                <span>{{ getHoursMinutesStringFromHoursFloat(props.value) }}</span>
                            </div>

                            <!-- any other fields, though time fields will have their own conditional class to highlight abnormalities -->
                            <div
                                v-else
                                class="q-px-xs"
                                :class="getListViewTimeCss(props.col.name, props.value).classes"
                            >
                                {{ TIME_COLUMNS.includes(props.col.name) ?
                                    getHoursMinutesStringFromHoursFloat(props.value) : props.value }}
                            </div>
                        </div>
                    </transition>
                </q-td>
            </template>

            <!-- Template for individual employee cards -->
            <template #item="props: { row: TimesheetApprovalOverview, rowIndex: number }">
                <OverviewListItem
                    v-model="props.row.is_approved"
                    :key="props.row.email + timesheet_store.pay_period?.pay_period_no"
                    :row="props.row"
                    @click-details="onClickedDetails"
                    @click-approval-all="is_approved => onClickApproveAll(props.row.email, is_approved)"
                />
            </template>

            <!-- Template for custome failed-to-load state -->
            <template #no-data="{ message, filter }">
                <div
                    v-if="!timesheet_store.is_loading"
                    class="full-width column items-center text-accent"
                >
                    <q-icon
                        size="4em"
                        :name="filter ? 'filter_alt_off' : 'error_outline'"
                    />

                    <span class="text-h6">
                        {{ message }}
                    </span>
                </div>
            </template>
        </q-table>
    </div>
</template>

<style
    lang="sass"
    scoped
>
.sticky-header-table
  thead tr:first-child th
    background-color: var(--q-accent)
    margin-top: none

  thead tr th
    position: sticky
    z-index: 1
  thead tr:first-child th
    top: 0px

  &.q-table--loading thead tr:last-child th
    top: 48px

  tbody
    scroll-margin-top: 48px

.q-table__grid-content
    overflow: auto

td
    min-width: 80px


.sticky-last-column-table    
    thead tr:last-child th:last-child
        background-color: $accent
        position: sticky
        z-index: 3

    thead tr:last-child th
        top: 0px

    td:last-child
        background-color: var(--q-dark)

    th:last-child,
    td:last-child
        position: sticky
        right: 0
        z-index: 1
        border-left: 3px solid $accent

.sticky-first-column-table
    thead tr:first-child th:first-child
        background-color: $accent
        position: sticky
        z-index: 3

    thead tr:first-child th
        top: 0px

    td:first-child
        background-color: var(--q-dark)

    th:first-child,
    td:first-child
        position: sticky
        left: 0
        z-index: 1
        border-right: 3px solid $accent
    
    :deep(tbody)
        overflow-x: scroll
</style>