<script setup>
import { onMounted, ref, reactive, onUnmounted, nextTick, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import FetchedTags from 'components/ui/FetchedTags.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import EditTableCellValueForm from 'src/components/EditTableCellValueForm.vue';
import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue';
import { useQuasar } from 'quasar';
import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue';
import { tMobile } from 'src/composables/tMobile';
import VnConfirm from 'components/ui/VnConfirm.vue';
import FetchData from 'src/components/FetchData.vue';
import { useStateStore } from 'stores/useStateStore';
import { toDate } from 'src/filters';
import { useVnConfirm } from 'composables/useVnConfirm';
import { useState } from 'src/composables/useState';
import useNotify from 'src/composables/useNotify.js';
import axios from 'axios';
import { isLower, isBigger } from 'src/filters/date.js';
import RightMenu from 'src/components/common/RightMenu.vue';
import VnTable from 'src/components/VnTable/VnTable.vue';
import { QCheckbox } from 'quasar';

const quasar = useQuasar();
const stateStore = useStateStore();
const { t } = useI18n();
const { openConfirmationModal } = useVnConfirm();
const state = useState();
const { notify } = useNotify();
const tableRef = ref();
const editTableCellDialogRef = ref(null);
const user = state.getUser();
const fixedPrices = ref([]);
const warehousesOptions = ref([]);
const rowsSelected = ref([]);
const itemFixedPriceFilterRef = ref();
const params = reactive({});

onMounted(async () => {
    stateStore.rightDrawer = true;
    params.warehouseFk = user.value.warehouseFk;
});
onUnmounted(() => (stateStore.rightDrawer = false));

const defaultColumnAttrs = {
    align: 'left',
    sortable: true,
};
const columns = computed(() => [
    {
        label: t('item.fixedPrice.itemFk'),
        name: 'itemFk',
        ...defaultColumnAttrs,
        isId: true,
        cardVisible: true,
        columnField: {
            component: 'input',
            type: 'number',
        },
        columnClass: 'shrink',
    },
    {
        label: t('globals.name'),
        field: 'name',
        name: 'description',
        ...defaultColumnAttrs,
        create: true,
        cardVisible: true,
    },
    {
        label: t('item.fixedPrice.groupingPrice'),
        field: 'rate2',
        name: 'rate2',
        ...defaultColumnAttrs,
        cardVisible: true,
        component: 'input',
        type: 'number',
    },
    {
        label: t('item.fixedPrice.packingPrice'),
        field: 'rate3',
        name: 'rate3',
        ...defaultColumnAttrs,
        cardVisible: true,
        component: 'input',
        type: 'number',
    },

    {
        label: t('item.fixedPrice.minPrice'),
        field: 'minPrice',
        name: 'minPrice',
        ...defaultColumnAttrs,
        cardVisible: true,
        component: 'input',
        type: 'number',
    },
    {
        label: t('item.fixedPrice.started'),
        field: 'started',
        name: 'started',
        format: ({ started }) => toDate(started),
        cardVisible: true,
        ...defaultColumnAttrs,
        columnField: {
            component: 'date',
            class: 'shrink',
        },
        columnFilter: {
            component: 'date',
        },
        columnClass: 'expand',
    },
    {
        label: t('item.fixedPrice.ended'),
        field: 'ended',
        name: 'ended',
        ...defaultColumnAttrs,
        cardVisible: true,
        columnField: {
            component: 'date',
            class: 'shrink',
        },
        columnFilter: {
            component: 'date',
        },
        columnClass: 'expand',
        format: (row) => toDate(row.ended),
    },

    {
        label: t('item.fixedPrice.warehouse'),
        field: 'warehouseFk',
        name: 'warehouseFk',
        ...defaultColumnAttrs,
        columnClass: 'shrink',
        component: 'select',

        options: warehousesOptions,
    },
    {
        align: 'right',
        name: 'tableActions',
        actions: [
            {
                title: t('delete'),
                icon: 'delete',
                action: (row) => confirmRemove(row),
                isPrimary: true,
            },
        ],
    },
]);

const editTableFieldsOptions = [
    {
        field: 'rate2',
        label: t('item.fixedPrice.groupingPrice'),
        component: 'input',
        attrs: {
            type: 'number',
        },
    },
    {
        field: 'rate3',
        label: t('item.fixedPrice.packingPrice'),
        component: 'input',
        attrs: {
            type: 'number',
        },
    },
    {
        field: 'minPrice',
        label: t('item.fixedPrice.minPrice'),
        component: 'input',
        attrs: {
            type: 'number',
        },
    },
    {
        field: 'started',
        label: t('item.fixedPrice.started'),
        component: 'date',
    },
    {
        field: 'ended',
        label: t('item.fixedPrice.ended'),
        component: 'date',
    },
    {
        field: 'warehouseFk',
        label: t('item.fixedPrice.warehouse'),
        component: 'select',
        attrs: {
            options: [],
            'option-label': 'name',
            'option-value': 'id',
        },
    },
];
const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => {
    return inputType === 'text'
        ? {
              'keyup.enter': () => upsertPrice(props, resetMinPrice),
              blur: () => upsertPrice(props, resetMinPrice),
          }
        : { 'update:modelValue': () => upsertPrice(props, resetMinPrice) };
};

const updateMinPrice = async (value, props) => {
    // El checkbox hasMinPrice se encuentra en la misma columna que el input hasMinPrice
    // Por lo tanto le mandamos otro objeto con las mismas propiedades pero con el campo 'field' cambiado
    props.row.hasMinPrice = value;
    await upsertPrice({
        row: props.row,
        col: { field: 'hasMinPrice' },
        rowIndex: props.rowIndex,
    });
};

const upsertPrice = async (props, resetMinPrice = false) => {
    try {
        const { row } = props;
        if (tableRef.value.CrudModelRef.getChanges().updates.length > 0) {
            if (resetMinPrice) row.hasMinPrice = 0;
            await upsertFixedPrice(row);
        }
    } catch (err) {
        console.error('Error editing price', err);
    }
};

async function upsertFixedPrice(row) {
    try {
        const { data } = await axios.patch('FixedPrices/upsertFixedPrice', row);
        return data;
    } catch (err) {
        console.error('Error editing price', err);
    }
}

async function saveOnRowChange(row) {
    if (rowsSelected.value.length > 1) return;
    if (rowsSelected.value[0]?.id === row.id) return;
    else if (rowsSelected.value.length === 1) await upsertPrice(rowsSelected.value[0]);
    rowsSelected.value = [row];
}

function checkLastVisibleRow() {
    let lastVisibleRow = null;

    getTableRows().forEach((row, index) => {
        const rect = row.getBoundingClientRect();
        if (rect.top >= 0 && rect.bottom <= window.innerHeight) {
            lastVisibleRow = index;
        }
    });

    return lastVisibleRow;
}

const addRow = (original = null) => {
    let copy = null;
    if (!original) {
        const today = Date.vnNew();
        const millisecsInDay = 86400000;
        const daysInWeek = 7;
        const nextWeek = new Date(today.getTime() + daysInWeek * millisecsInDay);

        copy = {
            id: 0,
            started: today,
            ended: nextWeek,
            hasMinPrice: 0,
            $index: 0,
        };
    } else
        copy = {
            $index: original.$index - 1,
            itemFk: original.itemFk,
            name: original.name,
            subName: original.subName,
            value5: original.value5,
            value6: original.value6,
            value7: original.value7,
            value8: original.value8,
            value9: original.value9,
            value10: original.value10,
            warehouseFk: original.warehouseFk,
            rate2: original.rate2,
            rate3: original.rate3,
            hasMinPrice: original.hasMinPrice,
            minPrice: original.minPrice,
            started: Date.vnNew(),
            ended: Date.vnNew(),
        };
    return { original, copy };
};

const getTableRows = () =>
    document.getElementsByClassName('q-table')[0].querySelectorAll('tr.cursor-pointer');

function highlightNewRow({ $index: index }) {
    const row = getTableRows()[index];
    if (row) {
        row.classList.add('highlight');
        setTimeout(() => {
            row.classList.remove('highlight');
        }, 3000); // Duración de la animación en milisegundos
    }
}
const openEditTableCellDialog = () => {
    editTableCellDialogRef.value.show();
};

const onEditCellDataSaved = async () => {
    rowsSelected.value = [];
    tableRef.value.reload();
};

const removeFuturePrice = async () => {
    try {
        rowsSelected.value.forEach(({ id }) => {
            const rowIndex = fixedPrices.value.findIndex(({ id }) => id === id);
            removePrice(id, rowIndex);
        });
    } catch (err) {
        console.error('Error removing price', err);
    }
};

function confirmRemove(item, isFuture) {
    const promise = async () =>
        isFuture ? removeFuturePrice(item.id) : removePrice(item.id);
    quasar.dialog({
        component: VnConfirm,
        componentProps: {
            title: t('globals.rowWillBeRemoved'),
            message: t('globals.confirmDeletion'),
            promise,
        },
    });
}

const removePrice = async (id) => {
    try {
        await axios.delete(`FixedPrices/${id}`);
        notify(t('globals.dataSaved'), 'positive');
        tableRef.value.reload({});
    } catch (err) {
        console.error('Error removing price', err);
    }
};
const dateStyle = (date) =>
    date
        ? {
              'bg-color': 'warning',
              'is-outlined': true,
          }
        : {};

function handleOnDataSave({ CrudModelRef }) {
    const { original, copy } = addRow(CrudModelRef.formData[checkLastVisibleRow()]);
    if (original) {
        CrudModelRef.formData.splice(original?.$index ?? 0, 0, copy);
    } else {
        CrudModelRef.insert(copy);
    }
    nextTick(() => {
        highlightNewRow(original ?? { $index: 0 });
    });
}
</script>

<template>
    <FetchData
        @on-fetch="(data) => (warehousesOptions = data)"
        auto-load
        url="Warehouses"
        :filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }"
    />
    <RightMenu>
        <template #right-panel>
            <ItemFixedPriceFilter
                data-key="ItemFixedPrices"
                ref="itemFixedPriceFilterRef"
            />
        </template>
    </RightMenu>
    <VnSubToolbar>
        <template #st-data>
            <QBtn
                v-if="rowsSelected.length"
                @click="openEditTableCellDialog()"
                color="primary"
                icon="edit"
            >
                <QTooltip>
                    {{ t('Edit fixed price(s)') }}
                </QTooltip>
            </QBtn>
            <QBtn
                :label="tMobile('globals.remove')"
                color="primary"
                icon="delete"
                flat
                @click="(row) => confirmRemove(row, true)"
                :title="t('globals.remove')"
                v-if="rowsSelected.length"
            />
        </template>
    </VnSubToolbar>
    <QPage>
        <VnTable
            @on-fetch="
                (data) =>
                    data.forEach((item) => {
                        item.hasMinPrice = `${item.hasMinPrice !== 0}`;
                    })
            "
            :default-remove="false"
            :default-reset="false"
            :default-save="false"
            data-key="ItemFixedPrices"
            url="FixedPrices/filter"
            :order="['description DESC']"
            save-url="FixedPrices/crud"
            :user-params="{ warehouseFk: user.warehouseFk }"
            ref="tableRef"
            dense
            :columns="columns"
            default-mode="table"
            auto-load
            :is-editable="true"
            :right-search="false"
            :table="{
                'row-key': 'id',
                selection: 'multiple',
            }"
            :crud-model="{
                paginate: false,
            }"
            v-model:selected="rowsSelected"
            :row-click="saveOnRowChange"
            :create-as-dialog="false"
            :create="{
                onDataSaved: handleOnDataSave,
            }"
            :use-model="true"
            :disable-option="{ card: true }"
        >
            <template #header-selection="scope">
                <QCheckbox v-model="scope.selected" />
            </template>
            <template #body-selection="scope">
                {{ scope }}
                <QCheckbox flat v-model="scope.selected" />
            </template>

            <template #column-itemFk="props">
                <VnSelect
                    style="max-width: 100px"
                    url="Items/withName"
                    hide-selected
                    option-label="id"
                    option-value="id"
                    v-model="props.row.itemFk"
                    v-on="getRowUpdateInputEvents(props, true, 'select')"
                >
                    <template #option="scope">
                        <QItem v-bind="scope.itemProps">
                            <QItemSection>
                                <QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
                                <QItemLabel caption>{{ scope.opt?.name }}</QItemLabel>
                            </QItemSection>
                        </QItem>
                    </template>
                </VnSelect>
            </template>
            <template #column-description="{ row }">
                <span class="link">
                    {{ row.name }}
                </span>
                <span class="subName">{{ row.subName }}</span>
                <ItemDescriptorProxy :id="row.itemFk" />
                <FetchedTags :item="row" />
            </template>
            <template #column-rate2="props">
                <QTd class="col">
                    <VnInput
                        type="currency"
                        style="width: 75px"
                        v-model.number="props.row.rate2"
                        v-on="getRowUpdateInputEvents(props)"
                    >
                        <template #append>€</template>
                    </VnInput>
                </QTd>
            </template>
            <template #column-rate3="props">
                <QTd class="col">
                    <VnInput
                        style="width: 75px"
                        type="currency"
                        v-model.number="props.row.rate3"
                        v-on="getRowUpdateInputEvents(props)"
                    >
                        <template #append>€</template>
                    </VnInput>
                </QTd>
            </template>
            <template #column-minPrice="props">
                <QTd class="col">
                    <div class="row" style="align-items: center">
                        <QCheckbox
                            :model-value="props.row.hasMinPrice"
                            @update:model-value="updateMinPrice($event, props)"
                            :false-value="'false'"
                            :true-value="'true'"
                        />
                        <VnInput
                            class="col"
                            type="currency"
                            mask="###.##"
                            :disable="props.row.hasMinPrice === 1"
                            v-model.number="props.row.minPrice"
                            v-on="getRowUpdateInputEvents(props)"
                        >
                            <template #append>€</template>
                        </VnInput>
                    </div>
                </QTd>
            </template>
            <template #column-started="props">
                <VnInputDate
                    class="vnInputDate"
                    :show-event="true"
                    v-model="props.row.started"
                    v-on="getRowUpdateInputEvents(props, false, 'date')"
                    v-bind="dateStyle(isBigger(props.row.started))"
                />
            </template>
            <template #column-ended="props">
                <VnInputDate
                    class="vnInputDate"
                    :show-event="true"
                    v-model="props.row.ended"
                    v-on="getRowUpdateInputEvents(props, false, 'date')"
                    v-bind="dateStyle(isLower(props.row.ended))"
                />
            </template>
            <template #column-warehouseFk="props">
                <QTd class="col">
                    <VnSelect
                        style="max-width: 150px"
                        :options="warehousesOptions"
                        hide-selected
                        option-label="name"
                        option-value="id"
                        v-model="props.row.warehouseFk"
                        v-on="getRowUpdateInputEvents(props, false, 'select')"
                    />
                </QTd>
            </template>
            <template #column-deleteAction="{ row, rowIndex }">
                <QIcon
                    name="delete"
                    size="sm"
                    class="cursor-pointer fill-icon-on-hover"
                    color="primary"
                    @click.stop="
                        openConfirmationModal(
                            t('globals.rowWillBeRemoved'),
                            t('Do you want to clone this item?'),
                            () => removePrice(row.id, rowIndex)
                        )
                    "
                >
                    <QTooltip class="text-no-wrap">
                        {{ t('globals.delete') }}
                    </QTooltip>
                </QIcon>
            </template>
        </VnTable>

        <QDialog ref="editTableCellDialogRef">
            <EditTableCellValueForm
                edit-url="FixedPrices/editFixedPrice"
                :rows="rowsSelected"
                :fields-options="editTableFieldsOptions"
                @on-data-saved="onEditCellDataSaved()"
            />
        </QDialog>
    </QPage>
</template>
<style lang="scss">
.q-table th,
.q-table td {
    padding-inline: 5px !important;
}
.q-table tr td {
    font-size: 10pt;
    border-top: none;
    border-collapse: collapse;
}
.q-table tbody td {
    max-width: none;
    .q-td.col {
        & .vnInputDate {
            min-width: 90px;
        }
        & div.row {
            & .q-checkbox {
                & .q-checkbox__inner {
                    position: relative !important;
                    &.q-checkbox__inner--truthy {
                        color: var(--q-primary);
                    }
                }
            }
        }
    }
}
.q-field__after,
.q-field__append {
    padding: 0;
}

tbody tr.highlight .q-td {
    animation: highlight-animation 4s ease-in-out;
}
@keyframes highlight-animation {
    0% {
        background-color: $primary-light;
    }
    100% {
        background-color: transparent;
    }
}
.subName {
    margin-left: 5%;
    font-size: 0.75rem;
    text-transform: uppercase;
    color: var(--vn-label-color);
}
</style>
<i18n>
es:
    Add fixed price: Añadir precio fijado
    Edit fixed price(s): Editar precio(s) fijado(s)
</i18n>
