https://dev.naayiq.com/products?page=1&search={query}&itemsPerPage=5 result is something like this:
{"products":[{"id":6,"name":"‏Anua Heartleaf Pore Clay Pack","description":"يقوم هذا القناع الطيني الكريمي بأمتصاص الزهم الزائد و إزالة الرؤوس السوداء بشكل فعال داخل المسام بسبب احتوائه Houttuynia Cordata الذي يتحكم في الدهون\nيحتوي على الكاولين لامتصاص الدهون\nيحتوي على مادة البنتونيت لتضييق المسام\nيحتوي على كيرسيتينول و هو المكون الرئيسي لأوراق القلب يوفر تهدئة البشرة ويتحكم في الدهون الزائدة لإزالة مشاكل المسام\nيعمل ايضا على إذابة خلايا الجلد الميتة القديمة على الجلد بلطف دون أي تهيج إضافة إلى تنعيم البشرة","brand_id":117,"has_color":false,"has_size":true,"product_type":"size","price":0,"qty":0,"sold":17,"created_at":"2024-08-24T00:51:27.907Z","updated_at":"2024-09-28T21:54:04.961Z","categories":[{"id":175,"name":"Masks","main_category_id":1,"main_category_name":"Face Care"}],"colors":[],"sizes":[{"id":1418,"name":"100 ML","price":22000,"qty":103,"sold":15,"color_id":null,"images":["1048.webp"]}],"images":[{"id":1588,"url":"1048.webp","color_id":null,"size_id":1418}]},{"id":7,"name":"‏Anua Heartleaf Pore Control CleanSsing Oil","description":"غسول منظف زيتي بالهارت ليف للمسامات من انوا\nمنظف زيتي بتركيبة لا تسبب انسداد المسامات ويحتوي على زيوت نباتية (بما في ذلك زيت الجوجوبا وفاكهة الزيتون وبذور العنب)، ويخلص البشرة من الشوائب بشكل فعال مع ترك لمسة نهائية منتعشة ورطبة. مناسب للبشرة المعرضة للحبوب.\nمميزاته وفوائده:\n‏* non-comedogenic تركيبة لا تسد المسامات مناسبة للبشرة الدهنية والمعرضة للحبوب\n* مستخلص هارتليف (houttuynia cordata) معروف جيدًا بتأثيره المضاد للالتهابات والمهدئ للبشرة.\n* مزيل مكياج خفيف يساعد على إزالة الشوائب في المسامات.\n* لا يحتوي على أي مواد مهيجة.\n* يحافظ على رطوبة بشرتك بعد التنظيف.\n* يناسب جميع انواع البشرات حتى الحساسة.","brand_id":117,"has_color":false,"has_size":true,"product_type":"size","price":0,"qty":0,"sold":106,"created_at":"2024-08-24T00:54:49.385Z","updated_at":"2024-09-29T11:35:40.995Z","categories":[{"id":168,"name":"Face Cleansers","main_category_id":1,"main_category_name":"Face Care"}],"colors":[],"sizes":[{"id":5043,"name":"200 ML","price":25000,"qty":0,"sold":104,"color_id":null,"images":[]}],"images":[{"id":9273,"url":"1049.webp","color_id":null,"size_id":null}]},{"id":11,"name":"Aveeno Daily Moisturising Hand Cream","description":"مرطب يد يومي من أفينو\nيتكون من دقيق الشوفان، تعمل هذه التركيبة سريعة الامتصاص على ترطيب البشرة لمدة 24 ساعة، فهو يساعد على حماية وتغذية اليد العادية إلى الجافة. يمنحك بشرة صحية وأكثر مرونة من الاستخدام الأول، لا يحتوي عطور و مناسب لبشرة اليد الحساسة.","brand_id":86,"has_color":false,"has_size":true,"product_type":"size","price":0,"qty":0,"sold":0,"created_at":"2024-08-24T15:43:56.173Z","updated_at":"2024-09-10T21:04:29.869Z","categories":[{"id":163,"name":"Hand moisturiser","main_category_id":6,"main_category_name":"Hand Care"}],"colors":[],"sizes":[{"id":1430,"name":"75 ml","price":12000,"qty":10,"sold":0,"color_id":null,"images":["1056.jpeg"]}],"images":[{"id":1600,"url":"1056.jpeg","color_id":null,"size_id":1430}]},{"id":44,"name":"Vichy ‏Beauty Deo Anti-perspirant","description":"‏مزيل تعرق طبي يساعد بعلاج التعرق المفرط ويخفي رائحة العرق المزعجه \nبمفعول يصل لمده 48 ساعة \nبالاضافه على قدرته بتفتيح منطقة الابط وتبيضها\nملائم للجلد الحساس يحتوي على حمض الليبوهيدروكسي و الحبيبات اللؤلؤية تعمل على تحسين مظهر البشرة وتفتيحها","brand_id":71,"has_color":false,"has_size":true,"product_type":"size","price":0,"qty":0,"sold":11,"created_at":"2024-08-24T19:37:55.009Z","updated_at":"2024-09-17T11:16:11.775Z","categories":[{"id":182,"name":"Deodorant","main_category_id":2,"main_category_name":"Body Care"}],"colors":[],"sizes":[{"id":886,"name":"50 ml","price":20000,"qty":3,"sold":11,"color_id":null,"images":["1728.jpeg"]}],"images":[{"id":2956,"url":"1728.jpeg","color_id":null,"size_id":886}]},{"id":45,"name":"VICHY DEODORANT MINERAL 48 H","description":"مزيل عرق من فيجي\nخالي من أملاح الألمنيوم، مع أقصى درجة من الفعالية والكفاءة، من خلال ربط المعادن الموجودة في مياه فيتشي الحرارية مع الzinc gluconate \nلفعالية تستمر لمدة 48 ساعة بالاضافة الى  Provitamine B5 الذي يعمل كمهدئ للبشرة.\nمناسب لجميع انواع البشرة خاصة البشرة الحساسة\nخالي من الكحول والبرابين.","brand_id":71,"has_color":false,"has_size":true,"product_type":"size","price":0,"qty":0,"sold":1,"created_at":"2024-08-24T19:40:27.610Z","updated_at":"2024-09-17T11:17:48.913Z","categories":[{"id":182,"name":"Deodorant","main_category_id":2,"main_category_name":"Body Care"}],"colors":[],"sizes":[{"id":888,"name":"50 ml","price":20000,"qty":32,"sold":1,"color_id":null,"images":["1730.jpeg"]}],"images":[{"id":2961,"url":"1730.jpeg","color_id":null,"size_id":888}]}],"total":298,"page":1,"itemsPerPage":5,"totalPages":60,"hasMore":true,"minPrice":0,"maxPrice":250000}
if hasMore is true, add show more options, when clicking showMore it should fetches the nextPage, page 2 and 3 and so on... handle when hasMore is false in that case you shouldn't show Show More...
Optimize the performance for this case...
'use client';
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { Search, X } from 'lucide-react';
import Image from 'next/image';
import debounce from 'lodash/debounce';
import Link from 'next/link';

const ProductSearchComponent = () => {
    const [query, setQuery] = useState('');
    const [recentSearches, setRecentSearches] = useState([]);
    const [bestSelling, setBestSelling] = useState([]);
    const [searchResults, setSearchResults] = useState([]);
    const [isFocused, setIsFocused] = useState(false);
    const [isLoading, setIsLoading] = useState(false);
    const inputRef = useRef(null);

    // Initialize recent searches and best-selling products
    useEffect(() => {
        // Load recent searches from localStorage
        const savedSearches = JSON.parse(localStorage.getItem('recentSearches') || '[]');
        setRecentSearches(savedSearches.slice(0, 5));

        // Fetch best selling products
        fetchBestSelling();
    }, []);

    // Fetch best-selling products
    const fetchBestSelling = useCallback(async () => {
        try {
            const response = await fetch(
                'https://dev.naayiq.com/products?page=1&sortBy=Best%20Selling&itemsPerPage=5&availability=in_stock'
            );
            if (!response.ok) {
                throw new Error('Network response was not ok');
            }
            const data = await response.json();
            setBestSelling(data.products);
        } catch (error) {
            console.error('Error fetching best selling products:', error);
        }
    }, []);

    // Update recent searches in state and localStorage
    const updateRecentSearches = useCallback(
        (search) => {
            if (search.trim() === '') return;
            const updatedSearches = [search, ...recentSearches.filter((s) => s !== search)].slice(0, 5);
            setRecentSearches(updatedSearches);
            localStorage.setItem('recentSearches', JSON.stringify(updatedSearches));
        },
        [recentSearches]
    );

    // Debounced search function
    const debouncedSearch = useCallback(
        debounce(async (searchQuery) => {
            if (searchQuery.trim() === '') {
                setSearchResults([]);
                return;
            }

            setIsLoading(true);
            try {
                const response = await fetch(
                    `https://dev.naayiq.com/products?page=1&search=${encodeURIComponent(searchQuery)}&itemsPerPage=5`
                );
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                const data = await response.json();
                setSearchResults(data.products);
                updateRecentSearches(searchQuery);
            } catch (error) {
                console.error('Error searching products:', error);
                setSearchResults([]);
            } finally {
                setIsLoading(false);
            }
        }, 300),
        [updateRecentSearches]
    );

    // Handle input change
    const handleSearch = (e) => {
        const newQuery = e.target.value;
        setQuery(newQuery);
        debouncedSearch(newQuery);
    };

    // Handle selection from recent searches
    const handleRecentSearch = (search) => {
        setQuery(search);
        debouncedSearch(search);
    };

    // Clear search input and results
    const handleClearSearch = () => {
        setQuery('');
        setSearchResults([]);
        if (inputRef.current) {
            inputRef.current.focus();
        }
    };

    // Render individual search items (best-selling products or search results)
    const renderSearchItem = (item) => (
        <Link
            key={item.id}
            href={`products/${item.id}`}
            prefetch={false}
            className="flex items-center space-x-2 p-2 hover:bg-gray-100 cursor-pointer"
            onClick={() => updateRecentSearches(item.name)}
        >
            {item.images && item.images[0] && (
                <Image
                    src={`https://storage.naayiq.com/resources/${item.images[0].url}`}
                    alt={item.name}
                    width={40}
                    height={40}
                    className="object-cover rounded"
                />
            )}
            <span className="flex-grow truncate">{item.name}</span>
        </Link>
    );

    // Cleanup debounced function on unmount
    useEffect(() => {
        return () => {
            debouncedSearch.cancel();
        };
    }, [debouncedSearch]);

    return (
        <div className="w-full mt-24 font-serif max-w-md mx-auto relative">

            {/* Search Input */}
            <div className="relative">
                <input
                    ref={inputRef}
                    type="text"
                    value={query}
                    onChange={handleSearch}
                    onFocus={() => setIsFocused(true)}
                    onBlur={() => setTimeout(() => setIsFocused(false), 200)}
                    placeholder="Search for product"
                    className="w-full p-2 pl-10 pr-10 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all"
                />
                <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
                {query && (
                    <button
                        onClick={handleClearSearch}
                        className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600 focus:outline-none"
                        aria-label="Clear search"
                    >
                        <X size={20} />
                    </button>
                )}
            </div>
            {!isFocused && recentSearches.length > 0 && (
                <div className="bg-white shadow rounded-md p-4">
                    <h3 className="text-sm font-medium text-gray-700 mb-2">Recent Searches</h3>
                    {recentSearches.map((search, index) => (
                        <div
                            key={index}
                            onClick={() => handleRecentSearch(search)}
                            className="flex items-center space-x-2 p-2 hover:bg-gray-100 cursor-pointer rounded"
                        >
                            <Search size={16} className="text-gray-400" />
                            <span>{search}</span>
                        </div>
                    ))}
                </div>
            )}

            {/* Dropdown: Suggestions or Search Results */}
            {isFocused && (query !== '' || searchResults.length > 0 || bestSelling.length > 0) && (
                <div className="absolute z-10 w-full mt-1 bg-white rounded-md shadow-lg max-h-96 overflow-y-auto">
                    {query === '' ? (
                        <>
                            {/* Search Suggestions */}
                            {bestSelling.length > 0 && (
                                <div className="p-4">
                                    <h3 className="text-sm font-medium text-gray-700 mb-2">Search Suggestions</h3>
                                    {bestSelling.map(renderSearchItem)}
                                </div>
                            )}
                        </>
                    ) : (
                        <>
                            {isLoading ? (
                                <div className="p-4 text-center text-gray-500">Loading...</div>
                            ) : searchResults.length > 0 ? (
                                searchResults.map(renderSearchItem)
                            ) : (
                                <div className="p-4 text-center text-gray-500">No products found</div>
                            )}
                        </>
                    )}
                </div>
            )}
        </div>
    );
};

export default ProductSearchComponent;