<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import axios from 'axios';
import FetchData from 'components/FetchData.vue';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
import VnInput from 'src/components/common/VnInput.vue';
import CatalogFilterValueDialog from 'src/pages/Order/Card/CatalogFilterValueDialog.vue';
import { useArrayData } from 'composables/useArrayData';

const props = defineProps({
    dataKey: {
        type: String,
        required: true,
    },
    tags: {
        type: Array,
        required: true,
    },
    tagValue: {
        type: Array,
        required: true,
    },
});

const { t } = useI18n();
const route = useRoute();

const arrayData = useArrayData(props.dataKey);

const categoryList = ref(null);
const typeList = ref([]);
const searchByTag = ref(null);

const vnFilterPanelRef = ref();
const orderByList = ref([
    { id: 'relevancy DESC, name', name: t('params.relevancy'), priority: 999 },
    { id: 'showOrder, price', name: t('params.colorAndPrice'), priority: 999 },
    { id: 'name', name: t('params.name'), priority: 999 },
    { id: 'price', name: t('params.price'), priority: 999 },
]);
const orderWayList = ref([
    { id: 'ASC', name: t('params.ASC') },
    { id: 'DESC', name: t('params.DESC') },
]);
const orderBySelected = ref('relevancy DESC, name');
const orderWaySelected = ref('ASC');

const resetCategory = (params, search) => {
    typeList.value = null;
    params.categoryFk = null;
    params.typeFk = null;
    arrayData.store.userFilter = null;
    search();
};

const selectCategory = async (params, category, search) => {
    if (vnFilterPanelRef.value.params.categoryFk === category?.id) {
        resetCategory(params, search);
        return;
    }
    params.typeFk = null;
    params.categoryFk = category.id;
    await loadTypes(category?.id);
};

const loadTypes = async (id) => {
    const { data } = await axios.get(`Orders/${route.params.id}/getItemTypeAvailable`, {
        params: { itemCategoryId: id },
    });
    typeList.value = data;
};

function exprBuilder(param, value) {
    switch (param) {
        case 'categoryFk':
        case 'typeFk':
            return { [param]: value };
        case 'search':
            if (/^\d+$/.test(value)) return { 'i.id': value };
            else return { 'i.name': { like: `%${value}%` } };
    }
}

const applyTags = (tagInfo, params, search) => {
    if (!tagInfo || !tagInfo.values.length) {
        params.tagGroups = null;
        search();
        return;
    }

    if (!params.tagGroups) params.tagGroups = [];
    params.tagGroups.push(tagInfo);
    search();
};

async function onSearchByTag(value) {
    if (!value.target.value) return;
    if (!vnFilterPanelRef.value.params?.tagGroups) {
        vnFilterPanelRef.value.params.tagGroups = [];
    }

    vnFilterPanelRef.value.params.tagGroups.push({
        values: [{ value: value.target.value }],
    });
    searchByTag.value = null;
}

const removeTagGroupParam = (params, search, valIndex) => {
    if (!valIndex && valIndex !== 0) {
        params.tagGroups = null;
    } else {
        params.tagGroups.splice(valIndex, 1);
    }
};

const setCategoryList = (data) => {
    categoryList.value = (data || [])
        .filter((category) => category.display)
        .map((category) => ({
            ...category,
            icon: `vn:${(category.icon || '').split('-')[1]}`,
        }));

    vnFilterPanelRef.value.params.categoryFk &&
        loadTypes(vnFilterPanelRef.value.params.categoryFk);
};

const getCategoryClass = (category, params) => {
    if (category.id === params?.categoryFk) {
        return 'active';
    }
};

function addOrder(value, field, params) {
    let { orderBy } = params;
    orderBy = JSON.parse(orderBy);
    orderBy[field] = value;
    params.orderBy = JSON.stringify(orderBy);
    vnFilterPanelRef.value.search();
}
</script>

<template>
    <FetchData url="ItemCategories" auto-load @on-fetch="setCategoryList" />
    <VnFilterPanel
        ref="vnFilterPanelRef"
        :data-key="props.dataKey"
        :hidden-tags="['filter', 'orderFk', 'orderBy']"
        :unremovable-params="['orderFk', 'orderBy']"
        :expr-builder="exprBuilder"
        :custom-tags="['tagGroups', 'categoryFk']"
        :redirect="false"
    >
        <template #tags="{ tag, formatFn }">
            <strong v-if="tag.label === 'typeFk' && typeList">
                {{ t(typeList.find((t) => t.id == tag.value)?.name || '') }}
            </strong>
            <div v-else class="q-gutter-x-xs">
                <strong>{{ t(`params.${tag.label}`) }}: </strong>
                <span>{{ formatFn(tag.value) }}</span>
            </div>
        </template>
        <template #customTags="{ params, tags: customTags, searchFn }">
            <template v-for="customTag in customTags" :key="customTag.label">
                <VnFilterPanelChip
                    v-for="(tag, valIndex) in Array.isArray(customTag.value)
                        ? customTag.value
                        : 1"
                    :key="valIndex"
                    removable
                    @remove="
                        customTag.label === 'categoryFk'
                            ? resetCategory(params, searchFn)
                            : removeTagGroupParam(params, searchFn, valIndex)
                    "
                    data-cy="catalogFilterCustomTag"
                >
                    <strong v-if="customTag.label === 'categoryFk' && categoryList">
                        {{
                            t(
                                categoryList.find((c) => c.id == customTag.value)?.name ||
                                    ''
                            )
                        }}
                    </strong>
                    <strong v-if="tag?.tagSelection?.name" class="q-mr-xs">
                        {{ tag.tagSelection.name }}:
                    </strong>
                    <span>
                        {{
                            (tag?.values || [])
                                .map((item) => `"${item.value}"`)
                                .join(', ')
                        }}
                    </span>
                </VnFilterPanelChip>
            </template>
        </template>
        <template #body="{ params, searchFn }">
            <QItem class="category-filter q-mt-md">
                <div
                    v-for="category in categoryList"
                    :key="category.name"
                    :class="['category', getCategoryClass(category, params)]"
                >
                    <QIcon
                        :name="category.icon"
                        class="category-icon"
                        @click="selectCategory(params, category, searchFn)"
                        data-cy="catalogFilterCategory"
                    >
                        <QTooltip>
                            {{ t(category.name) }}
                        </QTooltip>
                    </QIcon>
                </div>
            </QItem>
            <QItem class="q-my-md">
                <QItemSection>
                    <VnSelect
                        :label="t('params.type')"
                        v-model="params.typeFk"
                        :options="typeList"
                        option-value="id"
                        option-label="name"
                        dense
                        outlined
                        rounded
                        emit-value
                        use-input
                        sort-by="name ASC"
                        :disable="!params.categoryFk"
                        @update:model-value="searchFn()"
                        data-cy="catalogFilterType"
                    >
                        <template #option="{ itemProps, opt }">
                            <QItem v-bind="itemProps">
                                <QItemSection>
                                    <QItemLabel>{{ opt.name }}</QItemLabel>
                                    <QItemLabel caption>
                                        {{ opt.categoryName }}
                                    </QItemLabel>
                                </QItemSection>
                            </QItem>
                        </template>
                    </VnSelect>
                </QItemSection>
            </QItem>
            <QSeparator />
            <QItem class="q-mb-md">
                <QItemSection>
                    <VnSelect
                        :label="t('Order by')"
                        v-model="orderBySelected"
                        :options="orderByList"
                        dense
                        outlined
                        rounded
                        @update:model-value="(value) => addOrder(value, 'field', params)"
                    />
                </QItemSection>
            </QItem>
            <QItem class="q-my-md">
                <QItemSection>
                    <VnSelect
                        :label="t('Order')"
                        v-model="orderWaySelected"
                        :options="orderWayList"
                        dense
                        outlined
                        rounded
                        @update:model-value="(value) => addOrder(value, 'way', params)"
                    />
                </QItemSection>
            </QItem>
            <QSeparator />
            <QItem class="q-mt-lg q-pa-none">
                <VnInput
                    :label="t('components.itemsFilterPanel.value')"
                    dense
                    outlined
                    rounded
                    :is-clearable="false"
                    v-model="searchByTag"
                    @keyup.enter="(val) => onSearchByTag(val, params)"
                    data-cy="catalogFilterValueInput"
                >
                    <template #prepend>
                        <QIcon name="search" />
                    </template>
                    <template #append>
                        <QBtn
                            icon="add_circle"
                            shortcut="+"
                            flat
                            color="primary"
                            size="md"
                            dense
                            data-cy="catalogFilterValueDialogBtn"
                        />
                        <QPopupProxy>
                            <CatalogFilterValueDialog
                                style="display: inline-block"
                                :tags="tags"
                                @apply-tags="
                                    ($event) => applyTags($event, params, searchFn)
                                "
                            />
                        </QPopupProxy>
                    </template>
                </VnInput>
            </QItem>
            <QSeparator />
        </template>
    </VnFilterPanel>
</template>

<style lang="scss" scoped>
.category-filter {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;

    .category {
        flex: 1;
        flex-shrink: 0;
        display: flex;
        justify-content: center;

        &.active {
            .category-icon {
                background-color: $primary;
            }
        }
    }

    .category-icon {
        border-radius: 50%;
        background-color: var(--vn-accent-color);
        font-size: 2.6rem;
        padding: 8px;
        cursor: pointer;
    }
}
</style>

<i18n>
en:
    params:
        type: Type
        orderBy: Order By
        tag: Tag
        value: Value
        order: Order
        ASC: Ascendant
        DESC: Descendant
        relevancy: Relevancy
        colorAndPrice: Color and price
        name: Name
        price: Price
es:
    params:
        type: Tipo
        orderBy: Ordenar por
        tag: Etiqueta
        value: Valor
        order: Orden
        ASC: Ascendiente
        DESC: Descendiente
        relevancy: Relevancia
        colorAndPrice: Color y precio
        name: Nombre
        price: Precio
    Order: Orden
    Order by: Ordenar por
    Plant: Planta
    Flower: Flor
    Handmade: Confección
    Green: Verde
    Accessories: Complemento
    Fruit: Fruta
</i18n>
