import { toast } from "react-toastify";
import qs from 'qs';

import axiosInstance from "./axiosInstance";
import {
    getUrlPrefixForPreviews,
    resendOTP,
    verifyOTP,
    deleteCookie,
} from "../utility/utils";

let autocompleteService: google.maps.places.AutocompleteService | null = null;

const functions = {

    setClientStorage: (paramsObject: any) => {

        const PersistWay = paramsObject?.data?.persistIn;
        const KEY = paramsObject?.data?.persistKey;
        const Value = paramsObject?.data?.persistValue ?? '1';

        if (PersistWay === "localStorage") {
            localStorage.setItem(KEY, Value);
        }
        else if (PersistWay === "sessionStorage") {
            sessionStorage.setItem(KEY, Value);
        }
    },

    // @ts-ignore
    uploadFiles: async (paramsObject: any, mediaFiles: any, type: String = "single") => {
        try {
            type = type || "single";

            // console.log("paramsObject", paramsObject, type);
            let userCDN = process.env.USER_CDN_URL;
            let siteId: any = process.env.SITE_ID;

            if (!(mediaFiles instanceof FileList) || mediaFiles.length === 0) {
                // toast.error("Please select a file to upload.");
                return;
            }

            // Initialize FormData to hold the file data
            const formData = new FormData();

            // Append each files into formData() to upload
            Array.from(mediaFiles).forEach((file: any) => {
                formData.append("mediaFiles", file);
            });
            formData.append("siteId", siteId);

            try {
                const uploadedData = await (axiosInstance as any)().post(`${process.env.QAFTO_API_URL}/api/webpack/upload-files`,
                    formData,
                    {
                        headers: {
                            Authorization: `Bearer ${process.env.API_ACCESS_TOKEN}`,
                            Accept: "application/json"
                        }
                    }
                );

                // console.log("Upload response:", uploadedData);               
                toast.success("Upload successful!");

                if (type === "single") {
                    return `${userCDN}/${uploadedData?.data?.MediaCdnUrls[0]}`
                }

                let arr = [];
                for (const key of uploadedData?.data?.MediaCdnUrls) {
                    arr.push(`${userCDN}/${key}`);
                }
                return arr;

            } catch (error) {
                console.error("Upload error:", error);
                toast.error("Failed to upload media.");
                return
            }
        } catch (error) {
            toast.error("Something Went Wrong");
            console.log(error);
            return;
        }
    },

    showElement: ({ data }: any) => {
        try {
            document.getElementById(data.id)?.classList.remove('hidden');
        } catch (error) {
            throw error;
        }
    },

    hideElement: ({ data }: any) => {
        try {
            document.getElementById(data.id)?.classList.add('hidden');
        } catch (error) {
            throw error;
        }
    },

    toggleElement: ({ data }: any) => {
        try {
            if (document.getElementById(data.id)?.classList.contains('hidden')) {
                document.getElementById(data.id)?.classList.remove('hidden');
            } else {
                document.getElementById(data.id)?.classList.add('hidden');
            }
        } catch (error) {
            throw error;
        }
    },

    showAlert: ({ data }: any) => {
        try {
            alert(data.message);
        } catch (error) {
            throw error;

        }
    },

    animate: ({ data }: any) => {
        try {
            if (document.getElementById(data.id)?.classList.contains(data.animationName)) {
                document.getElementById(data.id)?.classList.remove(data.animationName);
                setTimeout(() => {
                    document.getElementById(data.id)?.classList.add(data.animationName)
                }, 100)
            }
            else {
                document.getElementById(data.id)?.classList.add(data.animationName)
            }
        } catch (error) {
            throw error;

        }
    },

    navigate: (paramsObject: any) => {
        try {
            const { data, props } = paramsObject;
            if (data.navigationType == 'Page') {
                const prefix = getUrlPrefixForPreviews(paramsObject);
                if (data.newTab == true) {
                    window.open(`${prefix}${data?.path == '/' ? (props.templatePreview || props.builderPreview) ? "" : '/' : data?.path}`);
                    return;
                } else {
                    props.navigate(`${prefix}${data?.path == '/' ? (props.templatePreview || props.builderPreview) ? "" : '/' : data?.path}`);
                    return;
                }
            } else if (data.navigationType == 'External Link') {
                if (data.newTab == true) {
                    window.open(data.link);
                } else {
                    window.open(data.link, '_self');
                }
            } else if (data.navigationType == 'Go Back') {
                props.navigate(-1);
            } else if (data.navigationType == 'Section') {
                document.getElementById(data.id)?.scrollIntoView({
                    behavior: 'smooth'
                });
            } else if (data.navigationType == 'Top Of Page') {
                window.scrollTo({ top: 0 })
            } else if (data.navigationType == 'Bottom Of Page') {
                window.scrollTo({ top: document.body.scrollHeight });
            }
        } catch (error) {
            throw error
        }
    },

    demo: () => {
    },

    focusOnInput: (paramsObject: any) => {
        try {
            const input: any = document.querySelector('input[name="' + paramsObject?.data?.field + '"]');
            if (input) {
                input.focus();
            }
        } catch (error) {
            console.log(error);

        }
    },

    setStateFromLocalStorage: (paramsObject: any) => {
        try {
            //@ts-ignore
            paramsObject[paramsObject.data.state](paramsObject.props.block.data.staticData);
        } catch (error) {
            throw error;

        }
    },

    clearLocalStorageKey: () => {

    },

    setStateNull: (paramsObject: any) => {
        try {
            paramsObject.props[paramsObject.data.state](null);
        } catch (error) {
            throw error;

        }
    },

    removeItemFromStateArrayAtClickedIndex: (paramsObject: any) => {
        try {
            paramsObject.props[paramsObject.data.state]((prev: any) => {
                const arr = [];
                for (let i = 0; i < prev?.length; i++) {
                    if (i != paramsObject.props.index) {
                        arr.push(prev[i]);
                    }
                }
                return arr;

            });
        } catch (error) {
            throw error;

        }
    },

    removeItemFromLocalStorageKeyArrayAtClickedIndex: () => {

    },

    changeValueOfKeyInObjectInLocalStorageKeyArrayAtParticularIndex: () => {

    },

    changeValueOfKeyInObjectInStateArrayAtParticularIndex: (paramsObject: any) => {
        try {
            paramsObject.props[paramsObject.data.state]((prev: any) => {
                const arr = [];
                for (let i = 0; i < prev?.length; i++) {
                    if (i != paramsObject.props.index) {
                        arr.push(prev[i]);
                    } else {
                        arr.push({
                            ...prev[i],
                            [paramsObject.data.objectKey]: paramsObject.e.target.value
                        });
                    }
                }
                return arr;

            });
        } catch (error) {
            throw error;

        }
    },

    incrementValueOfKeyInObjectInLocalStorageKeyArrayAtParticularIndex: () => {

    },

    decrementValueOfKeyInObjectInLocalStorageKeyArrayAtParticularIndex: () => {

    },

    incrementValueOfKeyInObjectInStateArrayAtParticularIndex: (paramsObject: any) => {
        try {
            paramsObject.props[paramsObject.data.state]((prev: any) => {
                const arr = [];
                for (let i = 0; i < prev?.length; i++) {
                    if (i != paramsObject.props.index) {
                        arr.push(prev[i]);
                    } else {
                        arr.push({
                            ...prev[i],
                            [paramsObject.data.objectKey]: prev[i][paramsObject.data.objectKey] + 1
                        });
                    }
                }
                return arr;

            });
        } catch (error) {
            throw error;

        }
    },

    decrementValueOfKeyInObjectInStateArrayAtParticularIndex: (paramsObject: any) => {
        try {
            paramsObject.props[paramsObject.data.state]((prev: any) => {
                const arr = [];
                for (let i = 0; i < prev?.length; i++) {
                    if (i != paramsObject.props.index) {
                        arr.push(prev[i]);
                    } else {
                        arr.push({
                            ...prev[i],
                            [paramsObject.data.objectKey]: ((prev[i][paramsObject.data.objectKey] - 1) >= 1) ? (prev[i][paramsObject.data.objectKey] - 1) : 1
                        });
                    }
                }
                return arr;

            });
        } catch (error) {
            throw error;

        }
    },

    changeValueOfState: (paramsObject: any) => {
        if (paramsObject?.props?.componentsPreview) {
            paramsObject?.e?.stopPropagation();
        }
        try {
            if (paramsObject.data.stateType == "object") {
                paramsObject.props[paramsObject.data.state]((prev: any) => {
                    let value;
                    if (paramsObject.data.type && paramsObject.data.type == 'toggle') {
                        value = !prev[paramsObject.data.objectKey];
                    } else if (paramsObject.data.type && paramsObject.data.type == 'increment') {
                        let val;
                        if (paramsObject.data.maximumValue) {
                            val = ((prev[paramsObject.data.objectKey] + 1) <= paramsObject.data.maximumValue) ? (prev[paramsObject.data.objectKey] + 1) : paramsObject.data.maximumValue
                        } else {
                            val = prev[paramsObject.data.objectKey] + 1;
                        }
                        value = val;
                    } else if (paramsObject.data.type && paramsObject.data.type == 'decrement') {
                        let val;
                        if (paramsObject.data.minimumValue) {
                            val = ((prev[paramsObject.data.objectKey] - 1) >= paramsObject.data.minimumValue) ? (prev[paramsObject.data.objectKey] - 1) : paramsObject.data.minimumValue
                        } else {
                            val = prev[paramsObject.data.objectKey] - 1;
                        }
                        value = val;
                    } else if (paramsObject.data.type && paramsObject.data.type == 'form') {
                        value = paramsObject.e.target.value;
                    } else if (paramsObject.data.type && paramsObject.data.type == 'custom') {
                        value = eval(paramsObject.data.value);
                    }
                    return {
                        ...prev,
                        [paramsObject.data.objectKey]: value
                    };

                });
            } else if (paramsObject.data.stateType == 'array') {
                paramsObject.props[paramsObject.data.state]((prev: any) => {
                    const arr = [];
                    for (let i = 0; i < prev?.length; i++) {
                        if (i != paramsObject.props.index) {
                            arr.push(prev[i]);
                        } else {
                            let value;
                            if (paramsObject.data.type && paramsObject.data.type == 'toggle') {
                                value = !prev[i][paramsObject.data.objectKey];
                            } else if (paramsObject.data.type && paramsObject.data.type == 'increment') {
                                let val;
                                if (paramsObject.data.maximumValue) {
                                    val = ((prev[i][paramsObject.data.objectKey] + 1) <= paramsObject.data.maximumValue) ? (prev[i][paramsObject.data.objectKey] + 1) : paramsObject.data.maximumValue
                                } else {
                                    val = prev[i][paramsObject.data.objectKey] + 1;
                                }
                                value = val;
                            } else if (paramsObject.data.type && paramsObject.data.type == 'decrement') {
                                let val;
                                if (paramsObject.data.minimumValue) {
                                    val = ((prev[i][paramsObject.data.objectKey] - 1) >= paramsObject.data.minimumValue) ? (prev[i][paramsObject.data.objectKey] - 1) : paramsObject.data.minimumValue
                                } else {
                                    val = prev[i][paramsObject.data.objectKey] - 1;
                                }
                                value = val;
                            } else if (paramsObject.data.type && paramsObject.data.type == 'form') {
                                value = paramsObject.e.target.value;
                            } else if (paramsObject.data.type && paramsObject.data.type == 'custom') {
                                value = eval(paramsObject.data.value);
                            } else if (paramsObject.data.type && paramsObject.data.type == 'remove') {
                                continue;
                            }
                            arr.push({
                                ...prev[i],
                                [paramsObject.data.objectKey]: value
                            });
                        }
                    }
                    return arr;

                });
            } else {
                paramsObject.props[paramsObject.data.state]((prev: any) => {
                    let value;
                    if (paramsObject.data.type && paramsObject.data.type == 'toggle') {
                        value = !prev;
                    } else if (paramsObject.data.type && paramsObject.data.type == 'increment') {
                        let val;
                        if (paramsObject.data.maximumValue) {
                            val = ((prev + 1) <= paramsObject.data.maximumValue) ? (prev + 1) : paramsObject.data.maximumValue
                        } else {
                            val = prev + 1;
                        }
                        value = val;
                    } else if (paramsObject.data.type && paramsObject.data.type == 'decrement') {
                        let val;
                        if (paramsObject.data.minimumValue) {
                            val = ((prev - 1) >= paramsObject.data.minimumValue) ? (prev - 1) : paramsObject.data.minimumValue
                        } else {
                            val = prev - 1;
                        }
                        value = val;
                    } else if (paramsObject.data.type && paramsObject.data.type == 'form') {
                        value = paramsObject.e.target.value;
                    } else if (paramsObject.data.type && paramsObject.data.type == 'custom') {
                        value = eval(paramsObject.data.value);
                    }
                    return value;
                });
            }
        } catch (error) {
            throw error;

        }
    },


    // START - Auth Functions

    VerifyOTPDuringRegister: async (paramsObject: any) => {
        return verifyOTP(paramsObject, {
            api: "/v1/ecommerce/verify-otp-during-register",
            defaultNavigateTo: "/",
            loginUser: true,
        });
    },

    resendOtpRegister: async (paramsObject: any) => {
        return resendOTP(paramsObject, {
            api: "/v1/ecommerce/resend-otp",
            otpType: "verify_registration",
            previewMessage: "A verification OTP has been sent.",
        });
    },

    forgotPasswordOTP: async (paramsObject: any) => {

        // component preview or builder
        if (paramsObject?.props?.componentsPreview || paramsObject?.props?.builder) {
            return;
        }

        // template or builder preview
        if (paramsObject.props.templatePreview || paramsObject?.props?.builderPreview) {
            toast.success("OTP successfully sent");

            const prefix = getUrlPrefixForPreviews(paramsObject);
            paramsObject.props.navigate(paramsObject?.data?.navigateTo ? `${prefix}${paramsObject.data.navigateTo}` : `${prefix}/forgot-password/verify-otp`);
            return;
        }

        // API call from real website
        try {
            paramsObject.setSubmitting(true);
            paramsObject.props.contextVariables.setIsAnimating(true);

            let data: any = {};

            if (paramsObject.values.email || paramsObject.values.phone_number) {
                data = {
                    ...paramsObject.values
                }

            } else if (paramsObject.values.key) {
                const pattern = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/;
                const isEmail = pattern.test(paramsObject.values.key)

                data[isEmail ? 'email' : 'phone_number'] = paramsObject.values.key;
            }

            if (paramsObject.data.verify) {
                data = {
                    ...data,
                    ...paramsObject.data.verify
                }
            }

            const response = await axiosInstance(paramsObject).post(`/v1/ecommerce/resend-otp`, { ...data, otpType: "forgot_password", });

            const key = paramsObject.values.email || paramsObject.values.phone_number || paramsObject.values.key;
            if (key) sessionStorage.setItem("key", key);

            toast.success(response.data.message);

            paramsObject.props.navigate(paramsObject.data.navigateTo ? paramsObject.data.navigateTo : '/forgot-password/verify-otp');
        } catch (error) {
            throw error;
        } finally {
            paramsObject.setSubmitting(false);
            paramsObject.props.contextVariables.setIsAnimating(false);
        }
    },

    forgotPasswordVerifyOTP: async (paramsObject: any) => {
        return verifyOTP(paramsObject, {
            api: "/v1/ecommerce/forgot-password-verify-otp",
            defaultNavigateTo: "/reset-password",
            loginUser: false,
        });
    },

    resendOtpForgotPassword: async (paramsObject: any) => {
        return resendOTP(paramsObject, {
            api: "/v1/ecommerce/resend-otp",
            otpType: "forgot_password",
            previewMessage: "A password reset OTP has been sent.",
        });
    },

    logout: async (paramsObject: any) => {
        // component preview
        if (paramsObject?.props?.componentsPreview) {
            paramsObject?.e?.stopPropagation();
            paramsObject?.props?.contextVariables?.setUser(null);
            return;
        }

        // template or builder preview
        if (paramsObject?.props?.templatePreview || paramsObject?.props?.builderPreview) {
            paramsObject?.props?.contextVariables?.setUser(null);

            const prefix = getUrlPrefixForPreviews(paramsObject);
            paramsObject?.props?.navigate?.(`${prefix}/login`);

            return;
        }

        try {
            paramsObject?.props?.contextVariables?.setIsAnimating(true);

            // delete cookie
            deleteCookie('userToken');

            paramsObject?.props?.contextVariables?.setUser(null);
            paramsObject?.props?.navigate('/login');
        } catch (error) {
            throw error;
        } finally {
            paramsObject?.props?.contextVariables?.setIsAnimating(false);
        }
    },

    // END - Auth Functions


    countdown: (paramsObject: any) => {
        paramsObject.setSingleData(paramsObject.data.countdownValue)

        setInterval(() => {
            paramsObject.setSingleData((prev: any) => {
                if (prev > 0) {
                    return (prev - 1);
                } else {
                    return prev;
                }
            });
        }, 1000);
    },

    saveOrUpdateData: async (paramsObject: any) => {

        // component preview or builder
        if (paramsObject?.props?.componentsPreview || paramsObject?.props?.builder) {
            return;
        }

        // template or builder preview
        if (paramsObject?.props?.templatePreview || paramsObject?.props?.builderPreview) {
            toast.success(paramsObject?.data?.successMessage ? paramsObject?.data?.successMessage : "Data saved successfully");

            if (paramsObject?.data?.auth) {
                paramsObject?.props?.contextVariables?.setUser?.({
                    first_name: "Dummy",
                    last_name: "User",
                    email: "dummyuser@gmail.com",
                    phone_number: "919876543210",
                    username: "dummyuser123",
                    unique_id: paramsObject?.props?.builderPreview ? paramsObject?.props?.params?.projectId : sessionStorage.getItem("recordsIdentifier")
                });
            }

            if (paramsObject?.data?.navigateTo) {
                const prefix = getUrlPrefixForPreviews(paramsObject);
                paramsObject?.props?.navigate?.(`${prefix}${paramsObject?.data?.navigateTo === "/" ? "" : paramsObject?.data?.navigateTo}`);
            } else {
                paramsObject?.resetForm?.();
            }
            return;
        }

        // API call from real website
        try {
            paramsObject?.setSubmitting?.(true);
            paramsObject?.props?.contextVariables?.setIsAnimating?.(true);

            const apiUrl = paramsObject?.data?.customUrl ? eval(paramsObject?.data?.apiUrl) : paramsObject?.data?.apiUrl;

            let data = {
                ...paramsObject.values
            }

            if (paramsObject?.fileTypeFields) {
                let obj: any = {};

                for (const key in paramsObject?.fileTypeFields) {
                    // TODO: update it
                    // Send Upload file data and it's type as multiple or by default single
                    const uploadedData = await functions.uploadFiles(paramsObject, paramsObject?.values?.[key], paramsObject?.fileTypeFields?.[key]);
                    obj[key] = uploadedData;
                }

                data = { ...data, ...obj };
            }

            if (paramsObject?.data?.verify) {
                data = {
                    ...data,
                    ...paramsObject?.data?.verify
                }
            }

            // verify email during register
            if (paramsObject?.data?.verifyEmail) {
                data = {
                    ...data,
                    verifyEmail: paramsObject?.data?.verifyEmail
                }
            }

            const response = await (axiosInstance(paramsObject) as any)?.[paramsObject?.data?.method]?.(apiUrl, {
                data: {
                    ...data
                }
            });
            console.log('saveOrUpdateData response', response);

            // set user
            if (paramsObject?.data?.auth && response?.data?.data?.user) {
                paramsObject.props?.contextVariables?.setUser(response.data.data.user);
            }

            // verify email during register
            if (paramsObject?.data?.verifyEmail) {
                const key = paramsObject.values.email || paramsObject.values.phone_number || paramsObject.values.key;
                if (key) sessionStorage.setItem("key", key);
            }

            toast.success(paramsObject?.data?.successMessage ? paramsObject?.data?.successMessage : response?.data?.message);

            if (paramsObject?.data?.navigateTo) {
                paramsObject?.props?.navigate?.(paramsObject?.data?.navigateTo);
            } else {
                paramsObject?.resetForm?.();
            }
        } catch (error) {
            throw error;
        } finally {
            paramsObject?.setSubmitting?.(false);
            paramsObject?.props?.contextVariables?.setIsAnimating?.(false);
        }
    },

    getData: async (paramsObject: any) => {
        try {
            // console.log('paramsObject', paramsObject);

            paramsObject?.props?.contextVariables?.setIsAnimating?.(true);
            const setStaticData = eval(paramsObject?.data?.setStaticDataCondition);
            if (setStaticData) {
                paramsObject?.[paramsObject?.data?.state]?.(paramsObject?.props?.block?.data?.staticData);
                return;
            }
            if (paramsObject?.data?.fetchCondition) {
                const fetchData = eval(paramsObject?.data?.fetchCondition);
                if (!fetchData) {
                    return;
                }
            }

            const apiUrl = paramsObject?.data?.customUrl ? eval(paramsObject?.data?.apiUrl) : paramsObject?.data?.apiUrl;

            let method = paramsObject?.data?.method || "get";
            const response = await (axiosInstance(paramsObject) as any)?.[method]?.(apiUrl);
            if (paramsObject?.data?.setRecords === true) {
                paramsObject?.[paramsObject?.data?.state]?.(response?.data?.data?.records);
            }
            else {
                paramsObject?.[paramsObject?.data?.state]?.(response?.data?.data);
            }

        } catch (error) {
            throw error;
        } finally {
            paramsObject?.props?.contextVariables?.setIsAnimating?.(false);
        }
    },

    setAnyState: async (paramsObject: any) => {
        try {

            if (!paramsObject?.data?.state) throw new Error("State was not provided!");
            let value = paramsObject?.data?.value;

            if (paramsObject?.data?.customValue) {
                value = eval(paramsObject?.data?.customValue);
            }

            paramsObject?.[paramsObject?.data?.state]?.(value);

        } catch (error) {
            throw error;
        }
    },

    updateData: async (paramsObject: any) => {
        if (paramsObject.props.templatePreview || paramsObject.props.builderPreview) {
            window.location.reload();
        } else {

            try {
                paramsObject?.props.contextVariables?.setIsAnimating(true);
                let data1: any = {};

                for (const key in paramsObject?.data?.data) {
                    if (paramsObject?.data?.data?.hasOwnProperty(key)) {
                        data1[key] = eval(paramsObject?.data?.data[key]);
                    }
                }

                const apiUrl = paramsObject?.data?.customUrl ? eval(paramsObject?.data?.apiUrl) : paramsObject?.data?.apiUrl;

                let method = paramsObject?.data?.method;

                await (axiosInstance(paramsObject) as any)[method](`${apiUrl}`, {
                    data: data1
                });

                window.location.reload();


                return;
                // console.log("paramsObject", paramsObject);

            } catch (error) {
                throw error;
            }
            finally {
                paramsObject?.props.contextVariables?.setIsAnimating(false);
            }
        }
    },

    CreateAddress: async (paramsObject: any) => {
        if (paramsObject.props.builderPreview || paramsObject.props.templatePreview) {
            paramsObject?.props.contextVariables?.setIsAnimating(true);
            toast.success("Address Created Successfully");
            paramsObject?.props.contextVariables?.setGlobalVariable((prev: any) => ({ ...prev, currentAddressType: 'none' }));
            window.location.reload();
            paramsObject?.props.contextVariables?.setIsAnimating(false);

        } else {

            try {

                paramsObject?.props.contextVariables?.setIsAnimating(true);

                console.log("paramsObject", paramsObject);

                let apiUrl = paramsObject?.data?.apiUrl;
                let data1 = {
                    // either pick type from form or from state
                    type: paramsObject?.values?.type ?? paramsObject?.props.contextVariables?.globalVariable?.currentAddressType,
                    address: {
                        city: paramsObject?.values?.city,
                        country: paramsObject?.values?.country,
                        state: paramsObject?.values?.state,
                        pincode: paramsObject?.values?.pincode,
                        landmark: paramsObject?.values?.landmark,
                        address: paramsObject?.values?.address,
                        lat: paramsObject?.values?.lat,
                        lng: paramsObject?.values?.lng,
                        name: paramsObject?.values?.name,
                        phone: paramsObject?.values?.phone,
                    }
                }
                // Remove the fields who have undefined or null value
                data1 = JSON.parse(JSON.stringify(data1));

                if (data1?.address?.lat <= 0 || data1?.address?.lng <= 0) {
                    toast.error("Latitude or Longitude are blank")
                    console.log("lat and/or lng have a value of 0");
                    return;
                }


                await axiosInstance(paramsObject).post(`${apiUrl}`, {
                    data: data1
                });
                paramsObject?.props.contextVariables?.setGlobalVariable((prev: any) => ({ ...prev, currentAddressType: 'none' }));
                toast.success("Address Created Successfully");
                window.location.reload();
                return

            } catch (error) {
                throw error
            }
            finally {
                paramsObject?.props.contextVariables?.setIsAnimating(false);
            }
        }
    },

    updateCart: async (paramsObject: any) => {
        if (paramsObject?.props?.componentsPreview) {
            paramsObject?.e?.stopPropagation();
            return;
        }
        if (paramsObject?.props?.builderPreview || paramsObject?.props?.templatePreview) {
            if (!paramsObject?.props?.contextVariables?.user) {
                toast.error("Please login to access cart");
                return;
            }
            if (paramsObject?.data?.quantity === -1 && paramsObject?.props?.singleData?.quantity && (paramsObject?.props?.singleData?.quantity - 1 === 0)) {
                return;
            }
            toast.success("Cart updated");
            return;
        }
        try {
            if (!paramsObject?.props?.contextVariables?.user) {
                toast.error("Please login to access cart");
                return;
            }
            if (paramsObject?.data?.quantity === -1 && paramsObject?.props?.singleData?.quantity && (paramsObject?.props?.singleData?.quantity - 1 === 0)) {
                return;
            }
            paramsObject?.props?.contextVariables?.setIsAnimating(true);
            const response = await axiosInstance(paramsObject).put('/v1/ecommerce/update-cart', {
                productId: paramsObject?.props?.singleData?.productId,
                quantity: typeof (paramsObject?.data?.quantity) === "number" ? paramsObject?.data?.quantity : paramsObject?.props?.singleData?.quantity
            });
            toast.success(response.data.message);
        } catch (error) {
            throw error;
        } finally {
            paramsObject?.props?.contextVariables?.setIsAnimating(false);

        }
    },

    updateWishlist: async (paramsObject: any) => {
        if (paramsObject?.props?.builder || paramsObject?.props?.componentsPreview) {
            paramsObject?.e?.stopPropagation();
            return;
        }
        if (paramsObject?.props?.templatePreview || paramsObject?.props?.builderPreview) {
            if (!paramsObject?.props?.contextVariables?.user) {
                toast.error("Please login to add product to wishlist");
                return;
            }
            toast.success("Wishlist updated");
            return;
        }
        try {
            if (!paramsObject?.props?.contextVariables?.user) {
                toast.error("Please login to add product to wishlist");
                return;
            }
            paramsObject.props?.contextVariables?.setIsAnimating(true);
            const response = await axiosInstance(paramsObject).put('/v1/ecommerce/update-wishlist', {
                productId: paramsObject?.props?.singleData?.productId
            });
            toast.success(response.data.message);
        } catch (error) {
            throw error;
        } finally {
            paramsObject?.props?.contextVariables?.setIsAnimating?.(false);

        }
    },

    initMap: async (paramsObject: any) => {
        if (paramsObject.props.builderPreview || paramsObject.props.templatePreview) {

        } else {
            if (window.google && window.google.maps && window.google.maps.places) {
                autocompleteService = new window.google.maps.places.AutocompleteService();
            } else {
                console.error('Google Maps API is not loaded properly.');
            }
        }
    },

    changeProductVariation: (paramsObject: any) => {
        if (paramsObject?.props?.builder || paramsObject?.props?.componentsPreview) {
            return;
        }
        try {
            let obj;
            let arr = [];
            if (paramsObject.data.type == 'props') {
                for (let i = 0; i < paramsObject.props.previousData[1].singleData.urlKeysOfAllCombinations.length; i++) {
                    if (paramsObject.props.previousData[1].singleData.urlKeysOfAllCombinations[i][paramsObject.props.previousData[2].singleData] == paramsObject.props.singleData) {
                        arr.push(paramsObject.props.previousData[1].singleData.urlKeysOfAllCombinations[i]);
                    }
                }
                const demoObj = paramsObject.props.previousData[1].singleData.selectedVariantValues;
                delete demoObj[paramsObject.props.previousData[2].singleData];
                obj = demoObj;

            } else {
                for (let i = 0; i < paramsObject.props.previousData[1].singleData.urlKeysOfAllCombinations.length; i++) {
                    if (paramsObject.props.previousData[1].singleData.urlKeysOfAllCombinations[i][paramsObject.props.singleData] == paramsObject.e.target.value) {
                        arr.push(paramsObject.props.previousData[1].singleData.urlKeysOfAllCombinations[i]);
                    }
                }
                const demoObj = paramsObject.props.previousData[1].singleData.selectedVariantValues;
                delete demoObj[paramsObject.props.singleData];
                obj = demoObj;

            }
            let url_key;
            for (let i = 0; i < arr.length; i++) {
                let match = true;
                for (let x in obj) {
                    if (arr[i][x] != obj[x]) {
                        match = false;
                        break;
                    }
                }
                if (match == true) {
                    url_key = arr[i].url_key;
                    break;
                }
            }
            const value = url_key ?? arr?.[0]?.url_key;
            const prefix = getUrlPrefixForPreviews(paramsObject);
            if (paramsObject?.props?.templatePreview || paramsObject?.props?.builderPreview) {
                paramsObject?.props?.navigate?.(`${prefix}/product/${value}`);
                return;
            }
            paramsObject.props.navigate(`/product/${value}`);

        } catch (error) {
            throw error;
        }
    },

    handlePredictionsAndStore: async (paramsObject: any) => {
        if (paramsObject.props.builderPreview || paramsObject.props.templatePreview) {

        } else {

            clearTimeout(paramsObject.timerRef?.current);
            paramsObject.timerRef.current = setTimeout(async () => {
                const input: string = paramsObject.e.target.value;

                // Ensure Google Maps is initialized
                if (!autocompleteService) {
                    functions.initMap(paramsObject);
                }

                if (!autocompleteService) {
                    throw new Error('AutocompleteService is not initialized.');
                }

                try {
                    // Fetch place predictions restricted to India
                    const predictions = await new Promise<google.maps.places.AutocompletePrediction[]>((resolve, reject) => {
                        autocompleteService!.getPlacePredictions(
                            {
                                input,
                                componentRestrictions: { country: 'IN' } // Restrict results to India
                            },
                            (predictions, status) => {
                                if (status === window.google.maps.places.PlacesServiceStatus.OK) {
                                    resolve(predictions);
                                } else {
                                    reject(new Error('Failed to get place predictions'));
                                }
                            }
                        );
                    });

                    // Create a PlacesService instance
                    const placesService = new window.google.maps.places.PlacesService(document.createElement('div'));

                    // Fetch detailed information for each prediction
                    const detailedPredictions = await Promise.all(predictions.map(async (prediction) => {
                        return new Promise((resolve, reject) => {
                            placesService.getDetails({ placeId: prediction.place_id }, (place, status) => {
                                if (status === window.google.maps.places.PlacesServiceStatus.OK && place) {
                                    const addressComponents = place.address_components || [];
                                    const formattedAddress = {
                                        address: '',
                                        landmark: '',
                                        city: '',
                                        state: '',
                                        pincode: '',
                                        country: ''
                                    };

                                    // Extract address components
                                    addressComponents.forEach(component => {
                                        if (component.types.includes('street_number') || component.types.includes('route')) {
                                            formattedAddress.address += (formattedAddress.address ? ' ' : '') + component.long_name;
                                        }
                                        if (component.types.includes('locality')) {
                                            formattedAddress.city = component.long_name;
                                        }
                                        if (component.types.includes('sublocality')) {
                                            formattedAddress.landmark = component.long_name;
                                        }
                                        if (component.types.includes('administrative_area_level_1')) {
                                            formattedAddress.state = component.long_name;
                                        }
                                        if (component.types.includes('postal_code')) {
                                            formattedAddress.pincode = component.long_name;
                                        }
                                        if (component.types.includes('country')) {
                                            formattedAddress.country = component.long_name;
                                        }
                                    });

                                    // Return structured prediction with details
                                    resolve({
                                        geocode: {
                                            lat: place.geometry?.location?.lat() || null,
                                            lng: place.geometry?.location?.lng() || null
                                        },
                                        address: formattedAddress
                                    });
                                } else {
                                    reject(new Error('Failed to get place details'));
                                }
                            });
                        });
                    }));
                    console.log(detailedPredictions, "here is detailed prediction")
                    // Update state or global variable with detailed predictions
                    if (detailedPredictions.length > 0) {
                        paramsObject?.props?.contextVariables.setGlobalVariable((prev: any) => {
                            return { ...prev, placePredictions: detailedPredictions };
                        });
                    }

                    // console.log("Predictions state update", paramsObject.contextVariables);
                } catch (error) {
                    console.error('Error handling place predictions:', error);
                }
            }, 300)
        }
    },

    fetchCurrentLocation: async (paramsObject: any) => {
        if (paramsObject.props.builderPreview || paramsObject.props.templatePreview) {
            return;
        } else {
            return new Promise<{ geocode: { lat: number; lng: number }; address: Object }>((resolve, reject) => {
                // Check if Geolocation API is supported
                if (!navigator.geolocation) {
                    reject(new Error('Geolocation is not supported by this browser.'));
                    return;
                }
                // Get current position
                navigator.geolocation.getCurrentPosition(
                    async (position) => {
                        const { latitude, longitude } = position.coords;

                        // Create a Geocoder instance
                        const geocoder = new window.google.maps.Geocoder();

                        // Reverse geocode to get address from coordinates
                        geocoder.geocode(
                            { location: { lat: latitude, lng: longitude } },
                            (results, status) => {
                                if (status === window.google.maps.GeocoderStatus.OK && results[0]) {
                                    const addressComponents = results[0].address_components || [];
                                    const formattedAddress = {
                                        address: '',
                                        landmark: '',
                                        city: '',
                                        state: '',
                                        pincode: '',
                                        country: ''
                                    };
                                    // Extract address components
                                    addressComponents.forEach((component: any) => {
                                        if (component.types.includes('street_number') || component.types.includes('route')) {
                                            formattedAddress.address += (formattedAddress.address ? ' ' : '') + component.long_name;
                                        }
                                        if (component.types.includes('locality')) {
                                            formattedAddress.city = component.long_name;
                                        }
                                        if (component.types.includes('sublocality')) {
                                            formattedAddress.landmark = component.long_name;
                                        }
                                        if (component.types.includes('administrative_area_level_1')) {
                                            formattedAddress.state = component.long_name;
                                        }
                                        if (component.types.includes('postal_code')) {
                                            formattedAddress.pincode = component.long_name;
                                        }
                                        if (component.types.includes('country')) {
                                            formattedAddress.country = component.long_name;
                                        }
                                    });
                                    resolve({
                                        geocode: { lat: latitude, lng: longitude },
                                        address: addressComponents
                                    });
                                    paramsObject?.props?.contextVariables.setGlobalVariable((prev: any) => {
                                        return { ...prev, currentLocation: { geocode: { lat: latitude, lng: longitude }, address: formattedAddress } }
                                    })
                                } else {
                                    reject(new Error('Failed to get address from coordinates.'));
                                }
                            }
                        );
                    },
                    (error) => {
                        reject(new Error('Failed to get current location: ' + error.message));
                    },
                    {
                        enableHighAccuracy: true,
                        timeout: 5000,
                        maximumAge: 0,
                    }
                );
            });

        }
    },

    MapLocation: (paramsObject: any) => {
        if (paramsObject.props.templatePreview || paramsObject.props.builderPreview) {

        } else {

        }
        // Initialize the map centered at a default location
        const initialLocation = { lat: -34.397, lng: 150.644 };
        //@ts-ignore
        const map = new google.maps.Map(document.getElementById('mapLocation'), {
            zoom: 20,
            center: initialLocation
        });

        // Create a marker and place it on the map
        const marker = new google.maps.Marker({
            position: initialLocation,
            map: map,
            draggable: true
        });

        // Create a Geocoder object
        const geocoder = new google.maps.Geocoder();

        // Event listener for marker drag end
        google.maps.event.addListener(marker, 'dragend', function (event) {
            const latLng = event.latLng;
            geocoder.geocode({ location: latLng }, function (results, status) {
                if (status === 'OK') {
                    if (results[0]) {
                        //@ts-ignore
                        document.getElementById('info').innerHTML = `
                  <strong>Address:</strong> ${results[0].formatted_address}<br>
                  <strong>Geocode:</strong> ${latLng.lat()}, ${latLng.lng()}
                `;
                    } else {
                        //@ts-ignore
                        document.getElementById('info').innerHTML = 'No results found';
                    }
                } else {
                    //@ts-ignore
                    document.getElementById('info').innerHTML = `Geocoder failed due to: ${status}`;
                }
            });
        });
    },

    Shipping: async (paramsObject: any) => {
        const { props, orderId } = paramsObject;
        if (paramsObject.props.templatePreview || paramsObject.props.builderPreview) {
            return;
        } else {

            try {

                console.log("contextVariables", props.contextVariables);
                const defaultDelivery = await axiosInstance(paramsObject).get(
                    `/delivery-crendentials`, {
                    params: {
                        filters: {
                            default: true
                        }
                    }
                });
                console.log('defaultDelivery', defaultDelivery);

                if (defaultDelivery?.data?.data?.length == 0) {
                    toast.error("Delivery Provider not selected.")
                    return {
                        status: 'Failed',
                        message: 'Delivery not selected',
                    };
                }

                let OrderTable = await axiosInstance(paramsObject).get(`/orders/${orderId}`);

                console.log("OrderTable", OrderTable)
                const temp = OrderTable?.data?.data?.attributes;

                if (
                    defaultDelivery?.data?.data[0]?.attributes?.provider === 'porter'
                ) {
                    let obj = {
                        "delivery_instructions": {
                            "instructions_list": [
                                {
                                    "type": "text",
                                    "description": "Handle with care"
                                }
                            ]
                        },
                        "drop_details": {
                            "address": {
                                "street_address1": temp?.shipping_address?.address ?? "",
                                "landmark": temp?.shipping_address?.landmark ?? "",
                                "city": temp?.shipping_address?.city ?? "",
                                "state": temp?.shipping_address?.state ?? "",
                                "pincode": temp?.shipping_address?.pincode ?? "",
                                "country": temp?.shipping_address?.country ?? "",
                                "lat": temp?.shipping_address?.lat,
                                "lng": temp?.shipping_address?.lng,
                                "contact_details": {
                                    "name": temp?.shipping_address?.name ?? "",
                                    "phone_number": `${temp?.shipping_address?.country_code}${temp?.shipping_address?.phone}`
                                }
                            }
                        },
                        // TODO: Fill in with admin pickup details
                        "pickup_details": {
                            "address": {
                                "street_address1": "BTM Layout",
                                "landmark": "BTM Layout",
                                "city": "Bengaluru",
                                "state": "Karnataka",
                                "pincode": "560029",
                                "country": "India",
                                "lat": 12.947146336879577,
                                "lng": 77.62102993895199,
                                "contact_details": {
                                    "name": "Test Receiver",
                                    "phone_number": "+919876543210"
                                }
                            }
                        }

                    }
                    const res = await axiosInstance(paramsObject).post(
                        `/all-deliveries?type=createOrder`, { data: obj }
                    );

                    console.log('RESPONSE', res);
                    OrderTable = await axiosInstance(paramsObject).put(`/orders/${orderId}`, {
                        data: {
                            payment_provider: "RazorPay",
                            delivery_provider: "porter",
                            deliveryId: res?.data?.order_id,
                            delivery_charge: res?.data?.estimated_fare_details?.minor_amount / 100    // To convert it from Paise to Ruppee
                        }
                    });
                    console.log("Updated Ordertable", OrderTable);
                }

                return;
            }

            catch (e) {
                console.log(e);
                return {
                    status: 'Failed',
                    message: 'Shipping failed',
                };
            }
        }
    },

    EstimateShippingFare: async (paramsObject: any) => {
        const { props } = paramsObject;

        if (paramsObject.props.templatePreview || paramsObject.props.builderPreview) {
            return;
        } else {

            try {
                // For estimation of shipping charges
                const defaultDelivery = await axiosInstance(paramsObject).get(
                    `/delivery-crendentials`,
                    {
                        params: {
                            filters: {
                                default: true,
                            },
                        },
                    });

                if (defaultDelivery?.data?.data?.length == 0) {
                    toast.error('Delivery Provider not selected.');
                    return {
                        status: 'Failed',
                        message: 'Delivery not selected',
                    };
                }

                const userId = props.contextVariables?.user?.id;
                if (!userId) {
                    return {
                        status: "Failed",
                        message: "No User Id"
                    }
                }


                if (
                    defaultDelivery?.data?.data[0]?.attributes?.provider === 'porter'
                ) {
                    const defaultAddress = await axiosInstance(paramsObject).get(`/users`, {
                        params: {
                            filters: {
                                address: {
                                    isactive: true,
                                    userId: userId,
                                    type: "shipping"
                                }
                            },
                            populate: {
                                address: {
                                    fields: ["address", "type"]
                                }
                            }
                        }
                    });

                    console.log("defaultAddress", defaultAddress);

                    if (defaultAddress?.data?.data?.length == 0) {
                        toast.error('Delivery Address not selected.');
                        return {
                            status: 'Failed',
                            message: 'Shipping Address not selected',
                        };
                    }

                    const temp = defaultAddress?.data?.data[0];

                    let obj = {
                        pickup_details: {   // TODO: Fill the pickup details from Admin Panel
                            lat: 12.935025018880504,
                            lng: 77.6092605236106,
                        },
                        drop_details: {
                            lat: temp?.address?.lat,
                            lng: temp?.address?.lng,
                        },
                        customer: {
                            name: temp?.address?.name,
                            mobile: {
                                country_code: temp?.address?.country_code,
                                number: temp?.address?.phone,
                            },
                        },
                    };

                    const res = await axiosInstance(paramsObject).post(
                        `all-deliveries?type=getQuote`,
                        { data: obj }
                    );

                    console.log('Estimation: ', res);   // This will give estimation fare for your Order
                }
                return;
            } catch (e) {
                console.log(e);
                return {
                    status: 'Failed',
                    message: 'Payment failed',
                };
            }
        }
    },

    handlePayment: async (paramsObject: any) => {
        const { props } = paramsObject;
        if (props?.templatePreview || props?.builderPreview) {
            toast.success("Payment Successfull");
            return;
        }
        else if (props?.componentsPreview) {
            return;
        }
        else {

            try {
                console.log("Here in Payment Function");

                let method = String(process.env.REACT_APP_CURRENT_PAYMENT_METHOD);

                if (method == "EaseBuzz") {
                    return await (functions as any).handleEaseBuzz();
                }

                else if (method == "RazorPay") {
                    return await functions.handlePaymentRazorpay(paramsObject);
                }

                else {
                    toast?.warning("Currently We don't support Online payments");

                    return {
                        status: "Failed",
                        message: "Default Online Payment is not selected"
                    }
                }

            } catch (e) {
                console.log(e)
                return {
                    status: "Failed",
                    message: "Payment failed"
                }
            }
        }
    },

    handlePaymentRazorpay: async (paramsObject: any) => {


        try {
            const RazorPay_APIKey: string | undefined = process.env.REACT_APP_RAZORPAY_KEY;

            if (!RazorPay_APIKey) {
                throw new Error("Payment can't be made!")
            }

            let userId = paramsObject?.props?.contextVariables?.user?.unique_id;
            // TODO: Fetch user from particular API because through this method all details have been fetched.
            let userData: any = await axiosInstance(paramsObject).get(`/v1/find/user?filters[unique_id]=${userId}`);

            if (userData?.data?.data?.records?.length == 0) {
                return {
                    status: "Failed",
                    message: "User not found"
                }
            }

            userData = userData?.data?.data?.records[0];

            const CartTotalData = await axiosInstance(paramsObject).get(`/v1/ecommerce/get-total`);
            console.log("CartTotalData", CartTotalData);

            const cartTotal = CartTotalData?.data?.data
                ?.total
            if (!cartTotal) {
                return {
                    status: "Failed",
                    message: "CartTotal is not valid"
                }
            }

            const createRazorPayOrder = await axiosInstance(paramsObject).post(`/v1/ecommerce/create-razorpay-order`, { amount: cartTotal });
            console.log("createRazorPayOrder", createRazorPayOrder)
            const order = createRazorPayOrder?.data?.data;


            const options = {

                key: RazorPay_APIKey,
                order_id: `${order?.id}`,
                name: userData?.first_name || "Qafto",
                description: "Payment for Products",
                image: userData?.profile_pic || "https://qafto.com/logo_new.svg",
                handler: async (response: any) => {

                    const validateData = await axiosInstance(paramsObject).post(`/v1/ecommerce/verify-razorpay-order`, { ...response });

                    console.log("validatedata", validateData)

                    if (validateData?.data?.isMatched === true) {

                        const CreatedOrder = await axiosInstance(paramsObject).post(`/v1/ecommerce/checkout`, {
                            data: {
                                orderId: order?.id,
                                status: "Success",
                                transactionId: response?.razorpay_payment_id,
                                amount: cartTotal,
                                planType: "Single",
                                payment_provider: "RazorPay"
                            }
                        });
                        console.log("After Checkout", CreatedOrder);

                        // Here If Call Automatic Shipping API
                        // const ship = await functions.Shipping({ contextVariables, createdOrderId });
                        // console.log("ship", ship);

                        toast.success("Payment Completed Successfully");
                        paramsObject.props?.navigate("/thank-you", {
                            state: { isPaid: true, orderId: CreatedOrder?.data?.data?.orderId, amount: cartTotal }
                        });
                    } else {
                        toast.error("Something went wrong")
                    }
                },
                config: {
                    display: {
                        hide: []
                    }
                },
                prefill: {
                    name: userData?.username || "xxxxx",
                    email: userData?.email || "xxxxx@gmail.com",
                    contact: userData?.phone_number || "0000000000"
                },
                theme: {
                    color: "#F37254"
                },
                method: {
                    upi: true,
                    netbanking: true,
                    wallet: true,
                    card: true
                }
            };

            let paymentObject = new (window as any).Razorpay(options);

            paymentObject.on('modal.dismiss', () => {
                console.log("User closed Razorpay checkout.");
                toast.warning("Payment was cancelled.");
            });

            paymentObject.on('payment.failed', async (response: any) => {

                console.log("Failed Response: ", response)
                console.log("orderId: ", response?.error?.metadata?.order_id)
                console.log("transactionId: ", response?.error?.metadata?.payment_id)
                await axiosInstance(paramsObject).post(`/v1/ecommerce/save-payment-logs`, {
                    data: {
                        orderId: response?.error?.metadata?.order_id,
                        transactionId: response?.error?.metadata?.payment_id,
                        status: "Failed",
                        amount: cartTotal,
                        planType: "Single",
                        payment_provider: "RazorPay"
                    }
                });

                toast.error(response.error.description);

                return {
                    status: "Failed",
                    message: "Payment failed"
                }
            });
            paymentObject.open();

            return {
                status: "Success",
                message: "Payment done Successfully"
            }

        } catch (error) {
            console.log(error);

            const errorMessage = (error as any)?.response?.data?.message || "Something went wrong";
            toast.error(errorMessage);
            return {
                code: 500,
                status: error?.toString(),
                message: "Something went wrong"
            }
        }

    },

    handleEaseBuzz: async (paramsObject: any) => {
        if (paramsObject.props.templatePreview || paramsObject.props.builderPreview) {

        } else {

            try {

                console.log("Here in EaseBuzz");

            } catch (error) {
                console.log(error);
            }
            finally {

            }
        }
    },

    verifyThankYou_Page: (paramsObject: any) => {
        try {

            console.log("Location State", paramsObject?.props?.location.state);
            if (paramsObject?.props?.location.state?.isPaid !== true) {
                paramsObject?.props?.navigate("/");
            }
            else {
                paramsObject?.[paramsObject?.data?.state]?.({ ...(paramsObject?.props?.location.state ?? {}) });
            }

            return;

        } catch (error) {
            console.log("error", error);
        }
    },

    changeSearchParams: async (paramsObject: any) => {
        if (paramsObject?.props?.componentsPreview || paramsObject?.props?.builder) {
            return;
        }
        try {
            if (paramsObject.data.debouncing) {
                clearTimeout(paramsObject.timerRef.current);
                paramsObject.timer.current = setTimeout(() => {
                }, paramsObject.data.delay);
            } else {
                if (paramsObject.data.type == 'form') {
                    if (paramsObject.values[paramsObject.data.key] == "") {
                        paramsObject.props.searchParams.delete(paramsObject.data.key);
                    } else {

                        paramsObject.props.searchParams.set(paramsObject.data.key, paramsObject.values[paramsObject.data.key]);
                    }
                    paramsObject.props.setSearchParams(paramsObject.props.searchParams);
                } else if (paramsObject.data.type == 'delete') {
                    paramsObject.props.searchParams.delete(paramsObject.data.key);
                    paramsObject.props.setSearchParams(paramsObject.props.searchParams);
                } else if (paramsObject.data.type == 'field') {
                    if (paramsObject.e.target.value == "") {
                        paramsObject.props.searchParams.delete(paramsObject.data.key);
                    } else {
                        paramsObject.props.searchParams.set(paramsObject.data.key, paramsObject.e.target.value);
                    }
                    paramsObject.props.setSearchParams(paramsObject.props.searchParams);
                } else if (paramsObject.data.type == 'singleData') {
                    if (paramsObject.props.searchParams.get(paramsObject.data.key) && paramsObject.props.searchParams.get(paramsObject.data.key) == paramsObject.props.singleData[paramsObject.data.fieldName].toString()) {
                        paramsObject.props.searchParams.delete(paramsObject.data.key);
                        if (paramsObject.data.key == 'category') {
                            paramsObject.props.searchParams.delete("variant");
                        }
                        paramsObject.props.setSearchParams(paramsObject.props.searchParams);

                    } else {
                        paramsObject.props.searchParams.set(paramsObject.data.key, paramsObject.props.singleData[paramsObject.data.fieldName]);
                        paramsObject.props.setSearchParams(paramsObject.props.searchParams);
                    }
                }
            }
        } catch (error) {
            throw error;
        }
    },
    changeVariantsValue: (paramsObject: any) => {
        if (paramsObject?.props?.componentsPreview || paramsObject?.props?.builder) {
            return;
        }
        const obj: any = qs.parse(paramsObject.props.location.search, { ignoreQueryPrefix: true });
        if (obj.variant) {
            if (obj.variant[paramsObject.props.previousData[2].singleData.name]) {
                if (obj.variant[paramsObject.props.previousData[2].singleData.name].includes(paramsObject.props.singleData.id.toString())) {

                    let index = obj.variant[paramsObject.props.previousData[2].singleData.name].indexOf(paramsObject.props.singleData.id.toString());
                    obj.variant[paramsObject.props.previousData[2].singleData.name].splice(index, 1);
                } else {
                    obj.variant[paramsObject.props.previousData[2].singleData.name].push(paramsObject.props.singleData.id.toString())
                }
            } else {
                obj.variant[paramsObject.props.previousData[2].singleData.name] = [paramsObject.props.singleData.id.toString()]
            }
        } else {
            obj.variant = {
                [paramsObject.props.previousData[2].singleData.name]: [paramsObject.props.singleData.id.toString()]
            }
        }
        const abx = qs.stringify(obj);
        paramsObject.props.setSearchParams(abx);
    },
    selectCategory: (paramsObject: any) => {
        if (paramsObject?.props?.componentsPreview || paramsObject?.props?.builder) {
            return;
        }
        const obj = qs.parse(paramsObject.props.location.search, { ignoreQueryPrefix: true });
        obj.category = paramsObject.props.singleData[paramsObject.data.fieldName];
        delete obj.variant;
        paramsObject.props.setSearchParams(qs.stringify(obj));
    },
    toggleBooleanTypeSearchParam: (paramsObject: any) => {
        if (paramsObject?.props?.componentsPreview || paramsObject?.props?.builder) {
            return;
        }
        if (paramsObject?.props?.searchParams?.get?.("showOutOfStockProducts")) {
            paramsObject?.props?.searchParams?.delete?.("showOutOfStockProducts");
        } else {
            paramsObject?.props?.searchParams.set?.("showOutOfStockProducts", "true");
        }
        paramsObject?.props?.setSearchParams?.(paramsObject?.props?.searchParams);

    },
    searchProduct: (paramsObject: any) => {
        if (paramsObject?.props?.componentsPreview || paramsObject?.props?.builder) {
            return;
        }
        if (paramsObject?.values?.[paramsObject?.data?.key] === "") {
            paramsObject?.props?.searchParams?.delete?.(paramsObject?.data?.key);
        } else {
            paramsObject?.props?.searchParams?.set?.(paramsObject?.data?.key, paramsObject?.values?.[paramsObject?.data?.key]);
        }

        if (paramsObject?.props?.templatePreview || paramsObject?.props?.builderPreview) {
            const prefix = getUrlPrefixForPreviews(paramsObject);
            paramsObject?.props?.navigate?.(`${prefix}/products?${paramsObject?.props?.searchParams}`);
        } else {
            paramsObject?.props?.navigate?.(`/products?${paramsObject.props.searchParams}`);
        }

    },
    unselectCategory: (paramsObject: any) => {
        if (paramsObject?.props?.componentsPreview || paramsObject?.props?.builder) {
            return;
        }
        const obj = qs.parse(paramsObject.props.location.search, { ignoreQueryPrefix: true });
        delete obj.category;
        delete obj.variant;
        paramsObject.props.setSearchParams(qs.stringify(obj));
    },
}

export default functions;