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

    import { computed, onMounted, ref } from 'vue';
    import { colors, getCssVar, QSelect } from 'quasar';
    import { useUiStore } from 'src/stores/ui-store';
    import { getCurrentDailyMinutesWorked, getShiftOptions, getTimeStringFromMinutes, SHIFT_OPTIONS } from 'src/modules/timesheets/utils/shift.util';
    import type { Shift, ShiftOption, ShiftType } from 'src/modules/timesheets/models/shift.models';
    import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-utils';

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

    const SHIFT_TYPES_WITH_PREDEFINED_TIMES: ShiftType[] = ['HOLIDAY', 'SICK', 'VACATION'];
    // const COMMENT_LENGTH_MAX = 280;

    const shift = defineModel<Shift>('shift', { required: true });

    const {
        currentShifts,
        hasShiftAfter = false,
        isTimesheetApproved = false,
        errorMessage = undefined,
        expectedDailyHours = 8,
    } = defineProps<{
        currentShifts: Shift[];
        hasShiftAfter?: boolean;
        isTimesheetApproved?: boolean;
        errorMessage?: string | undefined;
        expectedDailyHours?: number;
        isHoliday?: boolean;
    }>();

    const emit = defineEmits<{
        'requestDelete': [void];
        'onTimeFieldBlur': [void];
    }>();

    const uiStore = useUiStore();
    const shiftTypeSelected = ref(SHIFT_OPTIONS.find(option => option.value == shift.value.type));
    const selectRef = ref<QSelect | null>(null);
    // const isShowingCommentPopup = ref(false);
    const errorMessageRow = ref('');
    const isShowingPredefinedTime = ref(shift.value.type === 'HOLIDAY');
    const predefinedHoursString = ref('');
    const predefinedHoursBgColor = ref(`bg-${shiftTypeSelected.value?.icon_color ?? ''}`);

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

    const commentLength = computed(() => shift.value.comment?.length ?? 0);
    const isApproved = computed(() => isTimesheetApproved || shift.value.is_approved);
    const hasPTO = computed(() => currentShifts.some(shift => SHIFT_TYPES_WITH_PREDEFINED_TIMES.includes(shift.type)));

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

    const onBlurShiftTypeSelect = () => {
        if (shiftTypeSelected.value === undefined) {
            shift.value.type = 'REGULAR';
            shift.value.id = 0;
            emit('requestDelete');
        }
    };

    const onTimeFieldBlur = (time_string: string) => {
        if (time_string.length < 1 || !time_string) {
            shift.value.has_error = true;
            errorMessageRow.value = 'timesheet.errors.SHIFT_TIME_REQUIRED';
        } else {
            shift.value.has_error = false;
            errorMessageRow.value = '';
            emit('onTimeFieldBlur');
        }
    }

    const onShiftTypeChange = (option: ShiftOption) => {
        shift.value.type = option.value;

        if (SHIFT_TYPES_WITH_PREDEFINED_TIMES.includes(option.value)) {
            predefinedHoursBgColor.value = `bg-${option.icon_color}`;
            shift.value.start_time = '00:00';

            if (option.value === 'SICK' || option.value === 'VACATION') {
                const workedMinutes = getCurrentDailyMinutesWorked(currentShifts);
                const expectedWorkedMinutes = expectedDailyHours * 60;
                const leftOverMinutes = expectedWorkedMinutes - workedMinutes;

                shift.value.end_time = getTimeStringFromMinutes(leftOverMinutes);
                isShowingPredefinedTime.value = false;
            } else {
                isShowingPredefinedTime.value = true;
                predefinedHoursString.value = getHoursMinutesStringFromHoursFloat(expectedDailyHours);
                shift.value.end_time = getTimeStringFromMinutes(expectedDailyHours * 60);
            }
        } else
            isShowingPredefinedTime.value = false;
    }

    onMounted(() => {
        if (uiStore.focusNextComponent) {
            selectRef.value?.focus();
            selectRef.value?.showPopup();
            shiftTypeSelected.value = undefined;
            uiStore.focusNextComponent = false;
        }

        if (errorMessage)
            errorMessageRow.value = errorMessage;
    });
</script>

<template>
    <div class="column">
        <div class="column q-pa-sm">
            <div class="col column">
                <div class="row justify-center q-pb-xs q-px-sm full-width">
                    <!-- shift type -->
                    <q-select
                        ref="selectRef"
                        v-model="shiftTypeSelected"
                        dense
                        borderless
                        color="accent"
                        label-color="white"
                        stack-label
                        label-slot
                        hide-dropdown-icon
                        :readonly="isApproved"
                        :options="getShiftOptions(hasPTO, currentShifts.length > 1)"
                        lazy-rules
                        no-error-icon
                        hide-bottom-space
                        options-selected-class="text-white text-bold bg-accent"
                        class="col q-px-md rounded-5 inset-shadow text-uppercase"
                        :class="isApproved ? 'bg-white' : ($q.dark.isActive ? 'bg-primary' : 'bg-secondary')"
                        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 ${$q.dark.isActive ? 'var(--q-secondary)' : colors.getPaletteColor('blue-grey-4')}; background-color: ${colors.lighten(getCssVar('secondary')!, 50)}`"
                        @blur="onBlurShiftTypeSelect"
                        @update:model-value="onShiftTypeChange"
                    >
                        <template #selected-item="scope">
                            <div
                                class="row items-center text-weight-bold q-pt-sm no-wrap ellipsis"
                                :tabindex="scope.tabindex"
                            >
                                <q-icon
                                    :name="scope.opt.icon"
                                    :color="shift.is_approved ? 'accent' : scope.opt.icon_color"
                                    size="sm"
                                    class="col-auto"
                                    :class="shift.is_approved ? 'q-mx-xs' : 'q-mr-xs'"
                                />

                                <span
                                    style="font-size: 1.3em;"
                                    class="col ellipsis"
                                    :class="shift.is_approved ? 'text-accent' : ''"
                                >
                                    {{ $t(scope.opt.label) }}
                                </span>
                            </div>
                        </template>

                        <template #option="scope">
                            <q-item
                                clickable
                                v-bind="scope.itemProps"
                            >
                                <q-item-section avatar>
                                    <q-icon :name="scope.opt.icon" />
                                </q-item-section>

                                <q-item-section class="text-left">
                                    {{ $t(scope.label) }}
                                </q-item-section>
                            </q-item>
                        </template>

                        <!-- work-from-home toggle -->
                        <template #after>
                            <q-icon
                                v-if="shift.is_approved"
                                :name="shift.is_remote ? 'o_laptop' : 'o_business'"
                                size="1.2em"
                                color="accent"
                                class="q-mr-sm"
                            >
                                <q-tooltip
                                    anchor="top middle"
                                    self="bottom middle"
                                    :offset="[0, 10]"
                                    class="text-uppercase text-weight-bold text-white bg-primary"
                                >
                                    {{ shift.is_remote ? $t('timesheet.shift.types.REMOTE') :
                                        $t('timesheet.shift.types.OFFICE') }}
                                </q-tooltip>
                            </q-icon>

                            <q-toggle
                                v-else
                                v-model="shift.is_remote"
                                :disable="shift.is_approved"
                                dense
                                keep-color
                                size="3em"
                                :color="isHoliday ? 'purple-5' : 'accent'"
                                icon="las la-building"
                                checked-icon="las la-laptop"
                            >
                                <q-tooltip
                                    anchor="top middle"
                                    self="bottom middle"
                                    :offset="[0, 10]"
                                    class="text-uppercase text-weight-medium text-white bg-accent"
                                >
                                    {{ shift.is_remote ? $t('timesheet.shift.types.REMOTE') :
                                        $t('timesheet.shift.types.OFFICE') }}
                                </q-tooltip>
                            </q-toggle>
                        </template>

                        <template #label>
                            <span
                                class="text-weight-medium text-uppercase q-px-sm no-pointer-events"
                                :class="$q.dark.isActive ? 'bg-secondary' : 'bg-blue-grey-7'"
                            >
                                {{ $t('timesheet.shift.types.label') }}
                            </span>
                        </template>
                    </q-select>
                </div>

                <div
                    v-if="isShowingPredefinedTime"
                    class="col row items-start text-uppercase rounded-5 q-pa-xs relative-position"
                >
                    <div
                        class="absolute-full rounded-5 q-mx-sm q-my-xs"
                        :class="predefinedHoursBgColor"
                        style="opacity: 0.3;"
                    ></div>

                    <span class="col text-center text-uppercase text-h6 text-bold q-py-xs">
                        {{ getHoursMinutesStringFromHoursFloat(expectedDailyHours) }}
                    </span>
                </div>

                <div
                    v-else
                    class="col row items-start text-uppercase rounded-5 q-pt-sm"
                >
                    <!-- punch in field -->
                    <div class="col">
                        <TargoInput
                            v-model="shift.start_time"
                            no-top-padding
                            dense
                            type="time"
                            :readonly="isApproved"
                            :background-color="isApproved ? 'white' : undefined"
                            :input-text-color="isApproved ? 'accent' : ''"
                            :label="$t('shared.misc.in')"
                            :error="shift.has_error"
                            @blur="onTimeFieldBlur(shift.start_time)"
                        />
                    </div>

                    <!-- punch out field -->
                    <div class="col">
                        <TargoInput
                            v-model="shift.end_time"
                            no-top-padding
                            dense
                            type="time"
                            :readonly="isApproved"
                            :background-color="isApproved ? 'white' : undefined"
                            :input-text-color="isApproved ? 'accent' : ''"
                            :label="$t('shared.misc.out')"
                            :error="shift.has_error"
                            @blur="onTimeFieldBlur(shift.end_time)"
                        />
                    </div>
                </div>

                <div class="col-auto q-pt-md">
                    <TargoInput
                        v-model="shift.comment"
                        no-top-padding
                        dense
                        :readonly="isApproved"
                        :background-color="isApproved ? 'white' : undefined"
                        :input-text-color="isApproved ? 'accent' : ''"
                        :label="$t('timesheet.expense.employee_comment')"
                        :append-content="isApproved ? '' : `${commentLength ?? 0}/280`"
                    />
                </div>
            </div>

            <!-- Delete button at bottom of card -->
            <div
                v-if="!shift.is_approved"
                class="row justify-end q-px-sm q-pb-xs"
            >
                <q-btn
                    flat
                    dense
                    no-caps
                    color="negative"
                    icon="o_delete_outline"
                    label="Supprimer"
                    size="sm"
                    class="text-weight-medium"
                    @click="$emit('requestDelete')"
                />
            </div>
        </div>

        <q-separator
            v-if="hasShiftAfter"
            spaced
            size="2px"
            :color="isApproved ? 'accent2' : 'accent'"
            class="q-mx-lg"
        />
    </div>
</template>

<style scoped>
:deep(.q-field--error) {
    background-color: var(--q-negative) !important;
}

:deep(.q-field--error .q-field__bottom) {
    color: white;
    font-weight: 900;
    border-radius: 0 0 5px 5px;
    padding-top: 0;
    align-items: center;
}

:deep(.q-field--float .q-field__label) {
    transform: translate(-17px, -60%) scale(0.75) !important;
    border-radius: 10px 10px 10px 0px;
}

:deep(.q-field--auto-height.q-field--labeled .q-field__control-container) {
    padding: 0;
}
</style>