import {defineStore} from "pinia";
import {computed, ref} from "vue";
import {useProductStore} from "@/pinia/useProductStore";
import type {IFetchProductOptions} from "@/types/fetch-product-options-d-t";
import type {IProduct} from "@/types/product-d-t";
import type {IMeta} from "@/types/meta-d-t";
import type {TPagination} from "@/types/pagination-d-t";

export const useProductFilterStore = defineStore("product_filter", () => {
    const {t} = useI18n();
    const route = useRoute();
    const router = useRouter();
    const productStore = useProductStore();

    const product_data = ref<IProduct[]>(productStore?.product_data || []);
    const product_meta = ref<IMeta>(productStore?.product_meta || {} as IMeta);

    // todo: what max value should be?
    const maxProductPrice = computed(() => 10000000);

    const defaultSortingOption = ref<string>("");
    const sortingOption = ref<string>(defaultSortingOption.value);
    const getSortingOptions = () => {
        return [
            {value: '', text: t('Default Sorting')},
            {value: 'low-to-high', text: t('Low to High')},
            {value: 'high-to-low', text: t('High to Low')},
            {value: 'new-added', text: t('New Added')},
            {value: 'on-sale', text: t('On Sale')},
        ]
    };
    const findSortingOptionIndex = (v: string, sortingOptions?: []) => {
        // @ts-ignore
        sortingOptions = sortingOptions || getSortingOptions();
        // @ts-ignore
        return sortingOptions?.findIndex(option => option?.value === v);
    };
    const getSelectedSortingOptionIndex = ($sortingOption?: string, $sortingOptions?: []) => {
        // @ts-ignore
        $sortingOptions = $sortingOptions || getSortingOptions();
        $sortingOption = $sortingOption || sortingOption.value;
        // @ts-ignore
        return $sortingOptions.findIndex(option => option.value === $sortingOption) || 0;
    };
    const getSelectedSortingOption = () => getSortingOptions()[getSelectedSortingOptionIndex()];
    const fetchRouterSelectedSortingOption = () => {
        let q = router.currentRoute.value?.query;

        // @ts-ignore
        sortingOption.value = q.hasOwnProperty('sorting') ? q.sorting : defaultSortingOption.value;

        return sortingOption.value;
    };
    const handleSortingOptionFilter = () => {
        let query = {
            ...router.currentRoute.value?.query,
            sorting: sortingOption.value,
        }

        if (query.sorting === defaultSortingOption.value) {
            // @ts-ignore
            delete query.sorting;
        }

        router.push({query})
    };
    const handleSortingOptionChange = (e: { value: string; text: string }) => {
        sortingOption.value = e.value;

        return sortingOption.value;
    };
    const handleSortingOptionChangeAndFilter = (e: { value: string; text: string }) => {
        handleSortingOptionChange(e);
        handleSortingOptionFilter();
    };

    const defaultProductStatusOption = ref<number | null>(null);
    const productStatus = ref<number | null>(defaultProductStatusOption.value);
    const getProductStatusOptions = () => {
        return [
            t("On Sale"),
            t("In Stock")
        ]
    };
    const fetchRouterProductStatus = () => {
        let q = router.currentRoute.value?.query;

        productStatus.value = q.hasOwnProperty('status') ? Number(q.status) : defaultProductStatusOption.value;

        return productStatus.value;
    };
    const handleProductStatusFilter = () => {
        let query = {
            ...router.currentRoute.value?.query,
            status: productStatus.value,
        };
        if (productStatus.value == null) {
            // @ts-ignore
            delete query.status;
        }

        router.push({
            query
        })
    };
    const handleProductStatusChange = (e: number | null) => {
        if (productStatus.value !== e) {
            productStatus.value = e;
        } else {
            productStatus.value = null;
        }

        return productStatus.value;
    };
    const handleProductStatusChangeAndFilter = (e: number | null) => {
        handleProductStatusChange(e);
        handleProductStatusFilter();
    };

    const defaultProductCategory = ref<number | null>(null);
    const productCategory = ref<number | null>(defaultProductCategory.value);
    const fetchRouterProductCategory = () => {
        let q = router.currentRoute.value?.query;

        productCategory.value = q.hasOwnProperty('category') ? Number(q.category) : defaultProductCategory.value;

        return productCategory.value;
    };
    const handleProductCategoryFilter = () => {
        router.push({
            query: {
                ...router.currentRoute.value?.query,
                category: productCategory.value,
            }
        })
    };
    const handleProductCategoryChange = (e: number | null) => {
        productCategory.value = e;

        return productCategory.value;
    };
    const handleProductCategoryChangeAndFilter = (e: number | null) => {
        handleProductCategoryChange(e);
        handleProductCategoryFilter();
    };

    const defaultProductBrand = ref<number | null>(null);
    const productBrand = ref<number | null>(defaultProductBrand.value);
    const fetchRouterProductBrand = () => {
        let q = router.currentRoute.value?.query;

        productBrand.value = q.hasOwnProperty('brand') ? Number(q.brand) : defaultProductBrand.value;

        return productBrand.value;
    };
    const handleProductBrandFilter = () => {
        router.push({
            query: {
                ...router.currentRoute.value?.query,
                brand: productBrand.value,
            }
        })
    };
    const handleProductBrandChange = (e: number | null) => {
        productBrand.value = e;

        return productBrand.value;
    };
    const handleProductBrandChangeAndFilter = (e: number | null) => {
        handleProductBrandChange(e);
        handleProductBrandFilter();
    };

    const priceValues = ref([0, maxProductPrice.value]);
    const handlePriceChange = (value: number[]) => priceValues.value = value;
    const handlePriceChangeAndFilter = (value: number[]) => {
        handlePriceChange(value);
        handlePriceFilter();
    };
    const handlePriceFilter = () => {
        router.push({
            query: {
                ...router.currentRoute.value?.query,
                minPrice: priceValues.value?.[0],
                maxPrice: priceValues.value?.[1],
            }
        })
    };
    const fetchRouterPriceValues = (_q = undefined) => {
        let q = _q || router.currentRoute.value?.query;
        // @ts-ignore
        let v: [number, number] = [...priceValues.value];

        v[0] = q.hasOwnProperty('minPrice') ? Number(q.minPrice) : 0;
        v[1] = q.hasOwnProperty('maxPrice') ? Number(q.maxPrice) : maxProductPrice.value;

        priceValues.value = v;

        return priceValues.value;
    };

    const handleResetFilter = () => {
        productBrand.value = defaultProductBrand.value;
        productCategory.value = defaultProductCategory.value;
        productStatus.value = defaultProductStatusOption.value;
        priceValues.value = [0, maxProductPrice.value];
        sortingOption.value = defaultSortingOption.value;
    };
    const handlePageChange = (value: number) => productStore.updateCurrentPage(Math.ceil((value + 9) / 9));
    const loadProducts = (args?: IFetchProductOptions): Promise<IProduct[] | TPagination | TPagination<IProduct[]>> => productStore
            .loadProducts(args)
            .then((data: IProduct[] | TPagination | TPagination<IProduct[]>) => {
                // @ts-ignore
                debugger
                product_meta.value = productStore?.product_meta;
                product_data.value = data as IProduct[];
                return data;
            })

    const filterProducts = (filtered: IProduct[]) => {
        filtered = filtered || [];

        // Apply route-based filters (price, status, etc.)
        if (route.query.minPrice && route.query.maxPrice) {
            filtered = filtered.filter(
                (p) =>
                    Number(p?.price) >= Number(route.query.minPrice) &&
                    Number(p?.price) <= Number(route.query.maxPrice)
            );
        } else if (route.query.status) {
            if (route.query.status === "on-sale") {
                filtered = filtered.filter((p) => Number(p?.discount) > 0);
            } else if (route.query.status === "in-stock") {
                filtered = filtered.filter((p) => Number(p?.quantity) > 0);
            }
        } else if (route.query.category) {
            filtered = filtered.filter(
                (p) => {
                    return String(p?.parentCategory?.id).trim() === String(route.query.category).trim() || !(p?.parentCategory)
                }
            );
        } else if (route.query.subCategory) {
            filtered = filtered.filter(
                (p) => p.children.split(' ').join('-').toLowerCase() === route.query.subCategory
            );
        } else if (route.query.brand) {
            filtered = filtered.filter(
                (p) => p.brand_id === route.query.brand
            );
        }

        // Apply select filter (sorting)
        switch (sortingOption.value) {
            case "low-to-high":
                filtered.sort((a, b) => Number(a.price) - Number(b.price));
                break;
            case "high-to-low":
                filtered.sort((a, b) => Number(b.price) - Number(a.price));
                break;
            case "new-added":
                filtered = filtered.slice(-8);
                break;
            case "on-sale":
                filtered = filtered.filter((p) => Number(p?.discount) > 0);
                break;
        }

        return filtered;
    };

    const filteredProducts = computed(() => filterProducts([...(product_data.value || [])]));

    return {
        product_data,
        product_meta,
        maxProductPrice,

        sortingOption,
        defaultSortingOption,
        handleSortingOptionFilter,
        handleSortingOptionChange,
        handleSortingOptionChangeAndFilter,
        getSortingOptions,
        findSortingOptionIndex,
        getSelectedSortingOption,
        getSelectedSortingOptionIndex,
        fetchRouterSelectedSortingOption,

        productStatus,
        defaultProductStatusOption,
        getProductStatusOptions,
        handleProductStatusFilter,
        handleProductStatusChange,
        handleProductStatusChangeAndFilter,
        fetchRouterProductStatus,

        productCategory,
        defaultProductCategory,
        handleProductCategoryFilter,
        handleProductCategoryChange,
        handleProductCategoryChangeAndFilter,
        fetchRouterProductCategory,

        productBrand,
        defaultProductBrand,
        handleProductBrandFilter,
        handleProductBrandChange,
        handleProductBrandChangeAndFilter,
        fetchRouterProductBrand,

        priceValues,
        fetchRouterPriceValues,
        handlePriceFilter,
        handlePriceChange,
        handlePriceChangeAndFilter,

        handleResetFilter,
        handlePageChange,
        loadProducts,
        filteredProducts,
        filterProducts,

        updateCurrentPage: productStore.updateCurrentPage,
        currentProductOptions: productStore.currentProductOptions,
        updateProductOptions: (options: IFetchProductOptions) => {
            productStore.updateProductOptions(options);
            return options;
        },
        setData: (data: IProduct[]) => {
            productStore?.setData(data);
            try {
                product_data.value = data
            } catch (e) {
                console.error(e)
            }

            return data;
        },
        setMeta: (meta: IMeta) => {
            productStore?.setMeta(meta);
            try {
                product_meta.value = meta
            } catch (e) {
                console.error(e)
            }

            return meta;
        },
    };
});
