<script setup>
import { onMounted, computed, onUnmounted, reactive, ref, nextTick, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';

import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
import OrderDescriptorProxy from 'src/pages/Order/Card/OrderDescriptorProxy.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
import FetchData from 'components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';

import { useStateStore } from 'stores/useStateStore';
import { toDateFormat } from 'src/filters/date.js';
import { dashIfEmpty } from 'src/filters';
import { date } from 'quasar';
import { useState } from 'src/composables/useState';
import { useArrayData } from 'src/composables/useArrayData';
import axios from 'axios';

const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const stateStore = useStateStore();
const state = useState();

const user = state.getUser();
const today = ref(Date.vnNew());
const warehousesOptions = ref([]);
const itemBalancesRef = ref(null);
const itemsBalanceFilter = reactive({
    where: { itemFk: route.params.id, warehouseFk: null, date: null },
});
const itemBalances = ref([]);
const warehouseFk = ref(null);
const _showWhatsBeforeInventory = ref(false);
const inventoriedDate = ref(null);

const originTypeMap = {
    entry: {
        descriptor: EntryDescriptorProxy,
        icon: 'vn:entry',
        color: 'green',
    },
    ticket: {
        descriptor: TicketDescriptorProxy,
        icon: 'vn:ticket',
        color: 'red',
    },
    order: {
        descriptor: OrderDescriptorProxy,
        icon: 'vn:basket',
        color: 'yellow',
    },
};

const entityTypeMap = {
    client: {
        descriptor: CustomerDescriptorProxy,
    },
    supplier: {
        descriptor: SupplierDescriptorProxy,
    },
};

const columns = computed(() => [
    {
        name: 'claim',
        align: 'left',
        field: 'itemFk',
    },
    {
        label: t('itemDiary.date'),
        name: 'date',
        field: 'shipped',
        align: 'left',
    },
    {
        label: t('itemDiary.origin'),
        name: 'originId',
        align: 'left',
    },
    {
        label: t('itemDiary.state'),
        field: 'stateName',
        name: 'state',
        align: 'left',
        format: (val) => dashIfEmpty(val),
    },
    {
        label: t('itemDiary.reference'),
        field: 'reference',
        name: 'reference',
        align: 'left',
        format: (val) => dashIfEmpty(val),
    },

    {
        label: t('itemDiary.entity'),
        name: 'entityId',
        align: 'left',
        format: (val) => dashIfEmpty(val),
    },
    {
        label: t('itemDiary.in'),
        field: 'invalue',
        name: 'in',
        align: 'left',
        format: (val) => dashIfEmpty(val),
    },
    {
        label: t('itemDiary.out'),
        field: 'out',
        name: 'out',
        align: 'left',
        format: (val) => dashIfEmpty(val),
    },
    {
        label: t('itemDiary.balance'),
        name: 'balance',
        align: 'left',
    },
]);

const showWhatsBeforeInventory = computed({
    get: () => _showWhatsBeforeInventory.value,
    set: (val) => {
        _showWhatsBeforeInventory.value = val;
        if (!val) itemsBalanceFilter.where.date = null;
        else itemsBalanceFilter.where.date = inventoriedDate.value ?? new Date();
    },
});

onMounted(async () => {
    today.value.setHours(0, 0, 0, 0);
    if (route.query.warehouseFk) warehouseFk.value = route.query.warehouseFk;
    else if (user.value) warehouseFk.value = user.value.warehouseFk;
    itemsBalanceFilter.where.warehouseFk = warehouseFk.value;
    const { data } = await axios.get('Configs/findOne');
    inventoriedDate.value = data.inventoried;
    await fetchItemBalances();
    await scrollToToday();
    await updateWarehouse(warehouseFk.value);
});

onUnmounted(() => (stateStore.rightDrawer = false));

watch(
    () => router.currentRoute.value.params.id,
    (newId) => {
        itemsBalanceFilter.where.itemFk = newId;
        itemBalancesRef.value.fetch();
    }
);

const fetchItemBalances = async () => await itemBalancesRef.value.fetch();

const getBadgeAttrs = (_date) => {
    const isSameDate = date.isSameDate(today.value, _date);
    const attrs = {
        'text-color': isSameDate ? 'black' : 'white',
        color: isSameDate ? 'warning' : 'transparent',
    };
    return attrs;
};

const scrollToToday = async () => {
    await nextTick();
    const today = Date.vnNew();
    today.setHours(0, 0, 0, 0);
    const todayCell = document.querySelector(`td[data-date="${today.toISOString()}"]`);
    if (todayCell) {
        todayCell.scrollIntoView({ behavior: 'smooth', block: 'center' });
    }
};

const formatDateForAttribute = (dateValue) => {
    if (dateValue instanceof Date) return date.formatDate(dateValue, 'YYYY-MM-DD');
    return dateValue;
};

async function updateWarehouse(warehouseFk) {
    const stock = useArrayData('descriptorStock', {
        userParams: {
            warehouseFk,
        },
    });
    await stock.fetch({});
    stock.store.data.itemFk = route.params.id;
}
</script>

<template>
    <FetchData
        ref="itemBalancesRef"
        url="Items/getBalance"
        :filter="itemsBalanceFilter"
        @on-fetch="(data) => (itemBalances = data)"
    />
    <FetchData
        url="Warehouses"
        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
        auto-load
        @on-fetch="(data) => (warehousesOptions = data)"
    />
    <template v-if="stateStore.isHeaderMounted()">
        <Teleport to="#st-data">
            <div class="row">
                <VnSelect
                    :label="t('itemDiary.warehouse')"
                    :options="warehousesOptions"
                    hide-selected
                    option-label="name"
                    option-value="id"
                    dense
                    v-model="itemsBalanceFilter.where.warehouseFk"
                    @update:model-value="
                        (value) => fetchItemBalances() && updateWarehouse(value)
                    "
                    class="q-mr-lg"
                />
                <QCheckbox
                    :label="t('itemDiary.showBefore')"
                    v-model="showWhatsBeforeInventory"
                    @update:model-value="fetchItemBalances"
                    class="q-mr-lg"
                />
                <VnInputDate
                    v-if="showWhatsBeforeInventory"
                    :label="t('itemDiary.since')"
                    dense
                    v-model="itemsBalanceFilter.where.date"
                    @update:model-value="fetchItemBalances"
                />
            </div>
        </Teleport>
        <Teleport to="#st-actions"> </Teleport>
    </template>
    <QPage class="column items-center q-pa-md">
        <QTable
            :rows="itemBalances"
            :columns="columns"
            class="full-width q-mt-md"
            :no-data-label="t('globals.noResults')"
        >
            <template #body-cell-claim="{ row }">
                <QTd @click.stop>
                    <QBtn
                        v-show="row.claimFk"
                        flat
                        color="primary"
                        :to="{ name: 'ClaimSummary', params: { id: row.claimFk } }"
                        icon="vn:claims"
                        dense
                    >
                        <QTooltip>
                            {{ t('itemDiary.claim') }}: {{ row.claimFk }}
                        </QTooltip>
                    </QBtn>
                </QTd>
            </template>
            <template #body-cell-date="{ row }">
                <QTd @click.stop :data-date="formatDateForAttribute(row.shipped)">
                    <QBadge
                        v-bind="getBadgeAttrs(row.shipped)"
                        class="q-ma-none"
                        dense
                        style="font-size: 14px"
                    >
                        {{ toDateFormat(row.shipped) }}
                    </QBadge>
                </QTd>
            </template>
            <template #body-cell-originId="{ row }">
                <QTd @click.stop>
                    <component
                        :is="originTypeMap[row.originType]?.descriptor"
                        :id="row.originId"
                        class="q-ma-none"
                        dense
                        style="font-size: 14px"
                    >
                        {{ row.originId }}
                    </component>
                    <QIcon
                        :name="originTypeMap[row.originType]?.icon"
                        class="fill-icon q-mr-sm"
                        size="sm"
                        :color="originTypeMap[row.originType]?.color"
                    />
                    <span class="link">
                        {{ row.originId }}
                    </span>
                </QTd>
            </template>
            <template #body-cell-entityId="{ row }">
                <QTd @click.stop>
                    <QBadge
                        :color="row.highlighted ? 'warning' : 'transparent'"
                        :text-color="row.highlighted ? 'black' : 'white'"
                        dense
                        style="font-size: 14px"
                    >
                        <component
                            :is="entityTypeMap[row.entityType]?.descriptor"
                            :id="row.entityId"
                            class="q-ma-none"
                            dense
                            style="font-size: 14px"
                        >
                            {{ row.entityId }}
                        </component>
                        <span :class="{ link: row.entityId }">
                            {{ dashIfEmpty(row.entityName) }}
                        </span>
                    </QBadge>
                </QTd>
            </template>
            <template #body-cell-in="{ row }">
                <QTd @click.stop>
                    <span :class="{ 'is-in': row.invalue }">
                        {{ dashIfEmpty(row.invalue) }}
                    </span>
                </QTd>
            </template>
            <template #body-cell-balance="{ row }">
                <QTd @click.stop>
                    <QBadge
                        class="balance-negative"
                        :color="
                            row.lineFk == row.lastPreparedLineFk
                                ? 'grey-13'
                                : 'transparent'
                        "
                        :text-color="
                            row.lineFk == row.lastPreparedLineFk
                                ? 'black'
                                : row.balance < 0
                                ? 'negative'
                                : ''
                        "
                        dense
                        style="font-size: 14px"
                    >
                        <span>{{ dashIfEmpty(row.balance) }}</span>
                    </QBadge>
                </QTd>
            </template>
        </QTable>
    </QPage>
</template>

<style lang="scss" scoped>
.is-in {
    color: $positive;
}
</style>
