<script setup>
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import axios from 'axios';

import VnInput from 'components/common/VnInput.vue';
import FetchData from 'components/FetchData.vue';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';

const { t } = useI18n();
const route = useRoute();
const props = defineProps({
    dataKey: {
        type: String,
        required: true,
    },
    tags: {
        type: Array,
        required: true,
    },
});

const categoryList = ref(null);
const selectedCategoryFk = ref(null);
const typeList = ref(null);
const selectedTypeFk = ref(null);

const resetCategory = () => {
    selectedCategoryFk.value = null;
    typeList.value = null;
};

const selectedOrder = ref(null);
const orderList = [
    { way: 'ASC', name: 'Ascendant' },
    { way: 'DESC', name: 'Descendant' },
];

const selectedOrderField = ref(null);
const OrderFields = [
    { field: 'relevancy DESC, name', name: 'Relevancy', priority: 999 },
    { field: 'showOrder, price', name: 'Color and price', priority: 999 },
    { field: 'name', name: 'Name', priority: 999 },
    { field: 'price', name: 'Price', priority: 999 },
];

const clearFilter = (key) => {
    if (key === 'categoryFk') {
        resetCategory();
    }
};

const selectCategory = (params, category, search) => {
    if (params.categoryFk === category?.id) {
        resetCategory();
        params.categoryFk = null;
    } else {
        selectedCategoryFk.value = category?.id;
        params.categoryFk = category?.id;
        loadTypes(category?.id);
    }
    search();
};

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

const onFilterInit = async ({ params }) => {
    if (params.typeFk) {
        selectedTypeFk.value = params.typeFk;
    }
    if (params.categoryFk) {
        await loadTypes(params.categoryFk);
        selectedCategoryFk.value = params.categoryFk;
    }
    if (params.orderBy) {
        orderByParam.value = JSON.parse(params.orderBy);
        selectedOrder.value = orderByParam.value?.way;
        selectedOrderField.value = orderByParam.value?.field;
    }
};

const selectedCategory = computed(() =>
    (categoryList.value || []).find(
        (category) => category?.id === selectedCategoryFk.value
    )
);

const selectedType = computed(() => {
    return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value);
});

function exprBuilder(param, value) {
    switch (param) {
        case 'categoryFk':
        case 'typeFk':
            return { [param]: value };
        case 'search':
            return { 'i.name': { like: `%${value}%` } };
    }
}

const selectedTag = ref(null);
const tagValues = ref([{}]);
const tagOptions = ref(null);
const isButtonDisabled = computed(
    () => !selectedTag.value || tagValues.value.some((item) => !item.value)
);

const applyTagFilter = (params, search) => {
    if (!tagValues.value?.length) {
        params.tagGroups = null;
        search();
        return;
    }
    if (!params.tagGroups) {
        params.tagGroups = [];
    }
    params.tagGroups.push(
        JSON.stringify({
            values: tagValues.value,
            tagSelection: {
                ...selectedTag.value,
                orgShowField: selectedTag.value.name,
            },
            tagFk: selectedTag.value.tagFk,
        })
    );
    search();
    selectedTag.value = null;
    tagValues.value = [{}];
};

const removeTagChip = (selection, params, search) => {
    if (params.tagGroups) {
        params.tagGroups = (params.tagGroups || []).filter(
            (value) => value !== selection
        );
    }
    search();
};

const orderByParam = ref(null);

const onOrderFieldChange = (value, params, search) => {
    const orderBy = Object.assign({}, orderByParam.value, { field: value.field });
    params.orderBy = JSON.stringify(orderBy);
    search();
};

const onOrderChange = (value, params, search) => {
    const orderBy = Object.assign({}, orderByParam.value, { way: value.way });
    params.orderBy = JSON.stringify(orderBy);
    search();
};

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

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

<template>
    <FetchData url="ItemCategories" limit="30" auto-load @on-fetch="setCategoryList" />
    <VnFilterPanel
        :data-key="props.dataKey"
        :hidden-tags="['orderFk', 'orderBy']"
        :expr-builder="exprBuilder"
        :custom-tags="['tagGroups']"
        @init="onFilterInit"
        @remove="clearFilter"
    >
        <template #tags="{ tag, formatFn }">
            <strong v-if="tag.label === 'categoryFk'">
                {{ t(selectedCategory?.name || '') }}
            </strong>
            <strong v-else-if="tag.label === 'typeFk'">
                {{ t(selectedType?.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="{ tags: customTags, params, searchFn }">
            <template v-for="tag in customTags" :key="tag.label">
                <template v-if="tag.label === 'tagGroups'">
                    <VnFilterPanelChip
                        v-for="chip in tag.value"
                        :key="chip"
                        removable
                        @remove="removeTagChip(chip, params, searchFn)"
                    >
                        <strong> {{ JSON.parse(chip).tagSelection?.name }}: </strong>
                        <span>{{
                            (JSON.parse(chip).values || [])
                                .map((item) => item.value)
                                .join(' | ')
                        }}</span>
                    </VnFilterPanelChip>
                </template>
            </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)"
                    >
                        <QTooltip>
                            {{ t(category.name) }}
                        </QTooltip>
                    </QIcon>
                </div>
            </QItem>
            <QItem class="q-my-md">
                <QItemSection>
                    <VnSelectFilter
                        :label="t('params.type')"
                        v-model="params.typeFk"
                        :options="typeList"
                        option-value="id"
                        option-label="name"
                        dense
                        outlined
                        rounded
                        emit-value
                        use-input
                        :disable="!selectedCategoryFk"
                        @update:model-value="
                            (value) => {
                                selectedTypeFk = value;
                                searchFn();
                            }
                        "
                    >
                        <template #option="{ itemProps, opt }">
                            <QItem v-bind="itemProps">
                                <QItemSection>
                                    <QItemLabel>{{ opt.name }}</QItemLabel>
                                    <QItemLabel caption>
                                        {{ opt.categoryName }}
                                    </QItemLabel>
                                </QItemSection>
                            </QItem>
                        </template>
                    </VnSelectFilter>
                </QItemSection>
            </QItem>
            <QSeparator />
            <QItem class="q-my-md">
                <QItemSection>
                    <VnSelectFilter
                        :label="t('params.order')"
                        v-model="selectedOrder"
                        :options="orderList || []"
                        option-value="way"
                        option-label="name"
                        dense
                        outlined
                        rounded
                        :emit-value="false"
                        use-input
                        :is-clearable="false"
                        @update:model-value="
                            (value) => onOrderChange(value, params, searchFn)
                        "
                    />
                </QItemSection>
            </QItem>
            <QItem class="q-mb-md">
                <QItemSection>
                    <VnSelectFilter
                        :label="t('params.order')"
                        v-model="selectedOrderField"
                        :options="OrderFields || []"
                        option-value="field"
                        option-label="name"
                        dense
                        outlined
                        rounded
                        :emit-value="false"
                        use-input
                        :is-clearable="false"
                        @update:model-value="
                            (value) => onOrderFieldChange(value, params, searchFn)
                        "
                    />
                </QItemSection>
            </QItem>
            <QSeparator />
            <QItem class="q-mt-md">
                <QItemSection>
                    <VnSelectFilter
                        :label="t('params.tag')"
                        v-model="selectedTag"
                        :options="props.tags || []"
                        option-value="id"
                        option-label="name"
                        dense
                        outlined
                        rounded
                        :emit-value="false"
                        use-input
                    />
                </QItemSection>
            </QItem>
            <QItem
                v-for="(value, index) in tagValues"
                :key="value"
                class="q-mt-md filter-value"
            >
                <VnInput
                    v-if="selectedTag?.isFree"
                    v-model="value.value"
                    :label="t('params.value')"
                    is-outlined
                    class="filter-input"
                />
                <VnSelectFilter
                    v-else
                    :label="t('params.value')"
                    v-model="value.value"
                    :options="tagOptions || []"
                    option-value="value"
                    option-label="value"
                    dense
                    outlined
                    rounded
                    emit-value
                    use-input
                    :disable="!selectedTag"
                    class="filter-input"
                />

                <FetchData
                    v-if="selectedTag && !selectedTag.isFree"
                    :url="`Tags/${selectedTag?.id}/filterValue`"
                    limit="30"
                    auto-load
                    @on-fetch="(data) => (tagOptions = data)"
                />

                <QIcon
                    name="delete"
                    class="filter-icon"
                    @click="(tagValues || []).splice(index, 1)"
                />
            </QItem>
            <QItem class="q-mt-lg">
                <QIcon
                    name="add_circle"
                    class="filter-icon"
                    @click="tagValues.push({})"
                />
            </QItem>
            <QItem>
                <QItemSection class="q-py-sm">
                    <QBtn
                        :label="t('Search')"
                        class="full-width"
                        color="primary"
                        dense
                        icon="search"
                        rounded
                        type="button"
                        unelevated
                        :disable="isButtonDisabled"
                        @click.stop="applyTagFilter(params, searchFn)"
                    />
                </QItemSection>
            </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-light-gray);
        font-size: 2.6rem;
        padding: 8px;
        cursor: pointer;
    }
}

.filter-icon {
    font-size: 24px;
    color: $primary;
    padding: 0 4px;
    cursor: pointer;
}

.filter-input {
    flex-shrink: 1;
    min-width: 0;
}

.filter-value {
    display: flex;
    align-items: center;
}
</style>

<i18n>
en:
    params:
        type: Type
        orderBy: Order By
        tag: Tag
        value: Value
        order: Order
es:
    params:
        type: Tipo
        orderBy: Ordenar por
        tag: Etiqueta
        value: Valor
        order: Orden
    Plant: Planta
    Flower: Flor
    Handmade: Confección
    Green: Verde
    Accessories: Complemento
    Fruit: Fruta
</i18n>
