<script
    setup
    lang="ts"
>
    import { useI18n } from 'vue-i18n';
    import { computed, inject, onMounted, ref } from 'vue';
    import { QSelect, QInput, useQuasar, type QSelectProps, QPopupProxy } from 'quasar';
    import { useUiStore } from 'src/stores/ui-store';
    import { SHIFT_OPTIONS } from 'src/modules/timesheets/utils/shift.util';
    import type { Shift } from 'src/modules/timesheets/models/shift.models';
    import { useAuthStore } from 'src/stores/auth-store';

    // ================== State ==================

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

    const { errorMessage = undefined, isTimesheetApproved = false, holiday = false } = defineProps<{
        isTimesheetApproved?: boolean;
        errorMessage?: string | undefined;
        holiday?: boolean | undefined;
    }>();

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


    const COMMENT_LENGTH_MAX = 280;

    const q = useQuasar();
    const { t } = useI18n();
    const ui_store = useUiStore();
    const authStore = useAuthStore();

    const mode = inject<'normal' | 'approval'>('mode');

    const shiftTypeSelected = ref(SHIFT_OPTIONS.find(option => option.value == shift.value.type));
    const selectRef = ref<QSelect | null>(null);
    const shiftErrorMessage = ref<string | undefined>();
    const is_showing_delete_confirm = ref(false);
    const popupProxyRef = ref<QPopupProxy | null>(null);

    // ================== Computed ==================

    const rightClickMenuIcon = computed(() => shift.value.is_approved ? 'lock_open' : 'lock');

    const rightClickMenuLabel = computed(() => shift.value.is_approved ?
        t('timesheet_approvals.tooltip.unapprove') :
        t('timesheet_approvals.tooltip.approve'));

    const timeInputProps = computed(() => ({
        dense: true,
        borderless: shift.value.is_approved && isTimesheetApproved,
        readonly: shift.value.is_approved && isTimesheetApproved,
        standout: q.dark.isActive ? 'bg-blue-grey-3' : 'bg-blue-grey-9',
        labelSlot: true,
        lazyRules: true,
        noErrorIcon: true,
        hideBottomSpace: true,
        error: shift.value.has_error,
        errorMessage: errorMessage ? t(errorMessage) : (shiftErrorMessage.value ? t(shiftErrorMessage.value) : undefined),
        labelColor: shift.value.is_approved ? 'white' : (holiday ? 'purple-5' : 'accent'),
        class: `col rounded-5 bg-dark q-mx-xs ${shift.value.id === -2 ? 'bg-negative' : ''} ${shift.value.is_approved || isTimesheetApproved ? 'cursor-not-allowed inset-shadow' : ''}`,
        inputClass: `text-weight-medium ${shift.value.id === -2 ? 'text-white ' : ' '} ${shift.value.is_approved ? 'text-white cursor-not-allowed q-px-sm' : ''}`,
        style: shift.value.is_approved ? (holiday ? 'background-color: #7b1fa2 !important' : 'background-color: #0a7d32 !important;') : '',
        inputStyle: "font-size: 1.2em;"
    }));

    const shiftTypeSelectProps = computed<Partial<QSelectProps>>(() => ({
        standout: q.dark.isActive ? 'bg-blue-grey-3' : 'bg-blue-grey-9',
        dense: true,
        borderless: shift.value.is_approved && isTimesheetApproved,
        readonly: shift.value.is_approved && isTimesheetApproved,
        optionsDense: !ui_store.is_mobile_mode,
        hideDropdownIcon: true,
        menuOffset: [0, 10],
        menuAnchor: "bottom middle",
        menuSelf: "top middle",
        options: SHIFT_OPTIONS,
        class: `col rounded-5 q-mx-xs bg-dark ${!shift.value.is_approved && !isTimesheetApproved ? '' : 'inset-shadow'}`,
        popupContentClass: "text-uppercase text-weight-bold text-center rounded-5",
        style: shift.value.is_approved ? (holiday ? 'background-color: #7b1fa2 !important' : 'background-color: #0a7d32 !important;') : '',
        popupContentStyle: "border: 2px solid var(--q-accent)",
    }));

    // ================== Methods ==================

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

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

    const onConfirmDelete = () => {
        is_showing_delete_confirm.value = false;
        emit('requestDelete');
    }

    const getCommentCounterColor = (comment_length: number) => {
        if (comment_length < 200) return '';
        if (comment_length < 250) return 'warning';
        return 'negative';
    };

    const toggleIsShowingDeleteConfirm = (state: boolean) => {
        is_showing_delete_confirm.value = state;
    }

    const onRightClickApprove = () => {
        if (authStore.user?.user_module_access.includes('timesheets_approval'))
            shift.value.is_approved = !shift.value.is_approved;

        if (popupProxyRef.value)
            popupProxyRef.value.hide();
    }

    onMounted(() => {
        if (ui_store.focus_next_component) {
            selectRef.value?.focus();
            selectRef.value?.showPopup();
            shiftTypeSelected.value = undefined;
            ui_store.focus_next_component = false;
        }
    });
</script>

<template>
    <div class="row">
        <!-- right-click to approve shift only (if in approval mode) -->
        <q-popup-proxy
            v-if="mode === 'approval'"
            ref="popupProxyRef"
            context-menu
            class="rounded-5 q-px-md shadow-24 cursor-pointer"
            style="border: 3px solid var(--q-primary);"
        >
            <q-banner
                dense
                class="cursor-pointer q-px-lg"
                @click="onRightClickApprove"
            >
                <template v-slot:avatar>
                    <q-icon
                        :name="rightClickMenuIcon"
                        color="accent"
                    />
                </template>
                <span class="text-weight-bold text-accent text-uppercase">
                    {{ rightClickMenuLabel }}
                </span>
            </q-banner>
        </q-popup-proxy>

        <!-- delete shift confirmation dialog -->
        <q-dialog
            v-model="is_showing_delete_confirm"
            backdrop-filter="blur(6px)"
        >
            <div
                class="column flex-center q-pa-md bg-secondary shadow-24 rounded-10"
                style="border: 2px solid var(--q-accent);"
            >
                <span class="col-auto text-h6 text-bold text-uppercase">{{
                    $t('timesheet.shift.actions.delete_confirmation_msg') }}</span>
                <div class="row justify-right full-width">
                    <q-btn
                        flat
                        color="negative"
                        :label="$t('shared.misc.no')"
                        class="col"
                        @click="toggleIsShowingDeleteConfirm(false)"
                    />

                    <q-btn
                        flat
                        color="accent"
                        :label="$t('shared.misc.yes')"
                        class="col"
                        @click="onConfirmDelete"
                    />
                </div>
            </div>
        </q-dialog>

        <div
            class="row items-center text-uppercase rounded-5"
            :class="ui_store.is_mobile_mode ? 'col q-mb-xs q-px-xs' : 'col-4'"
        >
            <!-- shift type -->
            <q-select
                ref="selectRef"
                v-model="shiftTypeSelected"
                v-bind="shiftTypeSelectProps"
                @blur="onBlurShiftTypeSelect"
                @update:model-value="option => shift.type = option.value"
            >
                <template #selected-item="scope">
                    <div
                        class="row items-center text-weight-bold q-ma-none q-pa-none no-wrap ellipsis full-width"
                        :class="ui_store.is_mobile_mode ? 'full-height' : ''"
                        :tabindex="scope.tabindex"
                    >
                        <q-icon
                            :name="scope.opt.icon"
                            :color="shift.is_approved ? 'white' : scope.opt.icon_color"
                            size="sm"
                            class="col-auto"
                            :class="shift.is_approved ? 'q-mx-xs' : 'q-mr-xs'"
                        />
                        <span
                            style="line-height: 1.2em;"
                            class="col-auto ellipsis"
                            :class="!shift.is_approved ? '' : 'text-white'"
                        >
                            {{ $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 ? 'las la-laptop' : 'las la-building'"
                        size="1.2em"
                        color="white"
                        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="holiday ? '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>
            </q-select>
        </div>

        <div class="col row items-start text-uppercase rounded-5 q-pa-xs">
            <!-- punch in field -->
            <q-input
                ref="start_time"
                v-model="shift.start_time"
                v-bind="timeInputProps"
                type="time"
                @blur="onTimeFieldBlur(shift.start_time)"
            >
                <template #label>
                    <span
                        class="text-weight-bolder"
                        :class="shift.is_approved ? ' q-ml-md' : ''"
                        style="font-size: 0.95em;"
                    >{{ $t('shared.misc.in') }}</span>
                </template>
            </q-input>

            <!-- punch out field -->
            <q-input
                ref="end_time"
                v-model="shift.end_time"
                v-bind="timeInputProps"
                type="time"
                @blur="onTimeFieldBlur(shift.end_time)"
            >
                <template #label>
                    <span
                        class="text-weight-bolder"
                        :class="shift.is_approved ? ' q-ml-md' : ''"
                        style="font-size: 0.95em;"
                    >{{ $t('shared.misc.out') }}</span>
                </template>
            </q-input>

            <div
                class="row full-height"
                :class="ui_store.is_mobile_mode ? 'col-12' : 'col-auto flex-center'"
            >
                <!-- comment button -->
                <q-btn
                    v-if="!ui_store.is_mobile_mode"
                    push
                    dense
                    :color="shift.is_approved ? 'white' : (shift.comment ? 'accent' : (holiday ? 'purple-5' : 'blue-grey-5'))"
                    :icon="shift.comment ? 'chat' : 'chat_bubble_outline'"
                    :text-color="shift.is_approved ? (holiday ? 'purple-5' : 'accent') : 'white'"
                    class="col"
                    :class="ui_store.is_mobile_mode ? 'q-mt-xs bg-dark' : ''"
                >
                    <q-badge
                        v-if="shift.comment"
                        floating
                        rounded
                        color="info"
                        class="text-blue-9 text-weight-bolder"
                    >!!</q-badge>

                    <!-- popup to edit comment, with visual indicator of character limit -->
                    <q-popup-edit
                        v-model="shift.comment"
                        v-slot="scope"
                        auto-save
                        :max-width="$q.platform.is.mobile ? '' : '50vw'"
                        :title="$t('timesheet.shift.fields.header_comment')"
                        class="bg-dark full-width rounded-10"
                        style="border: 3px solid var(--q-accent);"
                    >
                        <q-input
                            color="white"
                            v-model="scope.value"
                            dense
                            :readonly="shift.is_approved"
                            autofocus
                            counter
                            bottom-slots
                            :maxlength="COMMENT_LENGTH_MAX"
                            class="q-pb-lg full-width"
                            :class="shift.is_approved ? 'cursor-not-allowed' : ''"
                            @keyup.enter="scope.set"
                        >
                            <template #append>
                                <q-icon name="edit" />
                            </template>

                            <template #counter>
                                <div class="row flex-center">
                                    <q-space />
                                    <q-knob
                                        :model-value="scope.value?.length"
                                        readonly
                                        :max="COMMENT_LENGTH_MAX"
                                        size="1.6em"
                                        :thickness="0.4"
                                        :color="getCommentCounterColor(scope.value?.length ?? 0)"
                                        track-color="grey-4"
                                        class="col-auto q-mr-xs"
                                    />
                                    <span
                                        :class="'col-auto text-weight-bolder text-' + getCommentCounterColor(scope.value?.length ?? 0)"
                                    >{{ 280 - (scope.value?.length ?? 0) }}</span>
                                </div>
                            </template>
                        </q-input>
                    </q-popup-edit>
                </q-btn>

                <!-- delete button -->
                <q-btn
                    v-if="!shift.is_approved"
                    flat
                    dense
                    :disable="shift.is_approved"
                    tabindex="-1"
                    icon="las la-trash"
                    text-color="negative"
                    class="col"
                    size="1.2em"
                    :class="shift.is_approved ? 'invisible' : ''"
                    @click="toggleIsShowingDeleteConfirm(true)"
                />
            </div>
        </div>
    </div>
</template>

<!-- styling the error message component to ressemble a red tab that
drops down, rather than the standard floating red text only -->
<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;
}
</style>