<script setup>
import axios from 'axios';
import { ref, reactive, useAttrs, computed } from 'vue';
import { onBeforeRouteLeave } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';

import { toDateHourMin } from 'src/filters';

import VnPaginate from 'components/ui/VnPaginate.vue';
import VnUserLink from 'components/ui/VnUserLink.vue';
import VnConfirm from 'components/ui/VnConfirm.vue';
import VnAvatar from 'components/ui/VnAvatar.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnSelect from 'components/common/VnSelect.vue';
import FetchData from 'components/FetchData.vue';
import VnInput from 'components/common/VnInput.vue';

const emit = defineEmits(['onFetch']);

const originalAttrs = useAttrs();

const $attrs = computed(() => {
    const { style, ...rest } = originalAttrs;
    return rest;
});

const isRequired = computed(() => {
    return Object.keys($attrs).includes('required');
});

const $props = defineProps({
    url: { type: String, default: null },
    saveUrl: { type: String, default: null },
    userFilter: { type: Object, default: () => {} },
    filter: { type: Object, default: () => {} },
    body: { type: Object, default: () => {} },
    addNote: { type: Boolean, default: false },
    selectType: { type: Boolean, default: false },
    justInput: { type: Boolean, default: false },
});

const { t } = useI18n();
const quasar = useQuasar();
const newNote = reactive({ text: null, observationTypeFk: null });
const observationTypes = ref([]);
const vnPaginateRef = ref();
let originalText;

function handleClick(e) {
    if (e.shiftKey && e.key === 'Enter') return;
    if ($props.justInput) confirmAndUpdate();
    else insert();
}

async function insert() {
    if (!newNote.text || ($props.selectType && !newNote.observationTypeFk)) return;

    const body = $props.body;
    const newBody = {
        ...body,
        ...{ text: newNote.text, observationTypeFk: newNote.observationTypeFk },
    };
    await axios.post($props.url, newBody);
    await vnPaginateRef.value.fetch();
}

function confirmAndUpdate() {
    if (!newNote.text && originalText)
        quasar
            .dialog({
                component: VnConfirm,
                componentProps: {
                    title: t('New note is empty'),
                    message: t('Are you sure remove this note?'),
                },
            })
            .onOk(update)
            .onCancel(() => {
                newNote.text = originalText;
            });
    else update();
}

async function update() {
    originalText = newNote.text;
    const body = $props.body;
    const newBody = {
        ...body,
        ...{ notes: newNote.text },
    };
    await axios.patch(
        `${$props.saveUrl ?? `${$props.url}/${$props.body.workerFk}`}`,
        newBody,
    );
}

onBeforeRouteLeave((to, from, next) => {
    if (
        (newNote.text && !$props.justInput) ||
        (newNote.text !== originalText && $props.justInput)
    )
        quasar.dialog({
            component: VnConfirm,
            componentProps: {
                title: t('globals.unsavedPopup.title'),
                message: t('globals.unsavedPopup.subtitle'),
                promise: () => next(),
            },
        });
    else next();
});

function fetchData([data]) {
    newNote.text = data?.notes;
    originalText = data?.notes;
    emit('onFetch', data);
}
</script>
<template>
    <FetchData
        v-if="selectType"
        url="ObservationTypes"
        :filter="{ fields: ['id', 'description'] }"
        auto-load
        @on-fetch="(data) => (observationTypes = data)"
    />
    <FetchData
        v-if="justInput"
        :url="url"
        :filter="filter"
        @on-fetch="fetchData"
        auto-load
    />
    <QCard
        class="q-pa-xs q-mb-lg full-width"
        :class="{ 'just-input': $props.justInput }"
        v-if="$props.addNote || $props.justInput"
    >
        <QCardSection horizontal v-if="!$props.justInput">
            {{ t('New note') }}
        </QCardSection>
        <QCardSection class="q-px-xs q-my-none q-py-none">
            <VnRow class="full-width">
                <VnSelect
                    :label="t('Observation type')"
                    v-if="selectType"
                    url="ObservationTypes"
                    v-model="newNote.observationTypeFk"
                    option-label="description"
                    style="flex: 0.15"
                    :required="isRequired"
                    @keyup.enter.stop="insert"
                />
                <VnInput
                    v-model.trim="newNote.text"
                    type="textarea"
                    :label="$props.justInput && newNote.text ? '' : t('Add note here...')"
                    filled
                    size="lg"
                    autogrow
                    @keyup.enter.stop="handleClick"
                    :required="isRequired"
                    clearable
                >
                    <template #append>
                        <QBtn
                            :title="t('Save (Enter)')"
                            icon="save"
                            color="primary"
                            flat
                            @click="handleClick"
                            class="q-mb-xs"
                            dense
                            data-cy="saveNote"
                        />
                    </template>
                </VnInput>
            </VnRow>
        </QCardSection>
    </QCard>
    <VnPaginate
        v-if="!$props.justInput"
        :data-key="$props.url"
        :url="$props.url"
        order="created DESC"
        :limit="0"
        :user-filter="userFilter"
        :filter="filter"
        auto-load
        ref="vnPaginateRef"
        class="show"
        v-bind="$attrs"
        search-url="notes"
        @on-fetch="
            newNote.text = '';
            newNote.observationTypeFk = null;
        "
    >
        <template #body="{ rows }">
            <TransitionGroup name="list" tag="div" class="column items-center full-width">
                <QCard
                    class="q-pa-xs q-mb-sm full-width"
                    v-for="(note, index) in rows"
                    :key="note.id ?? index"
                >
                    <QCardSection horizontal>
                        <VnAvatar
                            :descriptor="false"
                            :worker-id="note.workerFk"
                            size="md"
                            :title="note.worker?.user.nickname"
                        />
                        <div class="full-width row justify-between q-pa-xs">
                            <div>
                                <VnUserLink
                                    :name="`${note.worker.user.name}`"
                                    :worker-id="note.worker.id"
                                />
                                <QBadge
                                    class="q-ml-xs"
                                    outline
                                    color="grey"
                                    v-if="selectType && note.observationTypeFk"
                                >
                                    {{
                                        observationTypes.find(
                                            (ot) => ot.id === note.observationTypeFk,
                                        )?.description
                                    }}
                                </QBadge>
                            </div>
                            <span v-text="toDateHourMin(note.created)" />
                        </div>
                    </QCardSection>
                    <QCardSection class="q-pa-xs q-my-none q-py-none">
                        {{ note.text }}
                    </QCardSection>
                </QCard>
            </TransitionGroup>
        </template>
    </VnPaginate>
</template>
<style lang="scss" scoped>
.q-card {
    width: 90%;
}
.q-dialog .q-card {
    width: 400px;
}
.list-enter-active,
.list-leave-active {
    transition: all 1s ease;
}
.list-enter-from,
.list-leave-to {
    opacity: 0;
    background-color: $primary;
}

.vn-row > :nth-child(2) {
    margin-left: 0;
}

@media (max-width: $breakpoint-xs) {
    .vn-row > :deep(*) {
        margin-left: 0;
    }
    .q-card {
        width: 100%;

        &__section {
            padding: 0;
        }
    }
}
.just-input {
    padding-right: 18px;
    margin-bottom: 2px;
    box-shadow: none;
}
</style>
<i18n>
    es:
        Add note here...: Añadir nota aquí...
        New note: Nueva nota
        Save (Enter): Guardar (Intro)
        Observation type: Tipo de observación
        New note is empty: La nueva nota esta vacia
        Are you sure remove this note?: Estas seguro de quitar esta nota?
</i18n>
