import {ProductSchema} from "../../client";
import {FC, useState} from "react";
import useProductsList from "../../pages/ProductsPage/hooks/useProductsList.tsx";
import {omit} from "lodash";
import ObjectSelect, {ObjectSelectProps} from "../ObjectSelect/ObjectSelect.tsx";
import {ComboboxItem, Image, Loader, OptionsFilter, rem, SelectProps, Text, Tooltip} from "@mantine/core";
import {getProductFields} from "../../types/utils.ts";
import {useDebouncedValue} from "@mantine/hooks";

type RestProps = {
    clientId: number;
}
const MAX_PRODUCTS = 200;
type Props = Omit<ObjectSelectProps<ProductSchema>, 'data'> & RestProps;
const ProductSelect: FC<Props> = (props: Props) => {
    const [searchValue, setSearchValue] = useState("");
    const [debounced] = useDebouncedValue(searchValue, 500);
    const {products, isLoading} = useProductsList({
        clientId: props.clientId,
        searchInput: debounced,
        page: 0,
        itemsPerPage: MAX_PRODUCTS
    });
    const restProps = omit(props, ['clientId']);
    const renderOption: SelectProps['renderOption'] = (item) => {
        const product = products.find(product => product.id == parseInt(item.option.value));
        if (!product) return item.option.label;
        const productFields = getProductFields(product);
        const imageUrl = product.images && product.images[0] ? product.images[0].imageUrl : undefined;

        return (
            <Tooltip
                style={{whiteSpace: "pre-line"}}
                multiline
                disabled={productFields.length === 0}
                label={
                    <>
                        {productFields.map(([key, value]) => {
                            return `${key.toString()}: ${value.toString()}`;
                        }).join('\n')}
                        {imageUrl && <Image
                            src={imageUrl}
                            alt={product.name}
                            maw={rem(250)}
                        />}
                    </>
                }>
                <div>
                    {product.name}<br/>
                    {product.barcodes && <Text size={"xs"}>{product.barcodes[0]}</Text>}
                </div>
            </Tooltip>)
    }
    const optionsFilter: OptionsFilter = ({options, search}) => {
        return options;
        const filtered = (options as ComboboxItem[]).filter((option) => {
                const product = products.find(product => product.id == parseInt(option.value));
                if (!product) return true;
                return product.name.toLowerCase().includes(search.toLowerCase()) ||
                    product.barcodes.some((value) => value.toLowerCase().includes(search.toLowerCase())) ||
                    product.article?.toLowerCase() === search.toLowerCase();
            }
        );
        filtered.sort((a, b) => a.label.localeCompare(b.label));
        return filtered.length > MAX_PRODUCTS ? filtered.slice(0, MAX_PRODUCTS) : filtered;
    };
    const setSearchValueImpl = (value: string) => {
        const names = products.map(product => product.name);
        if (names.includes(value)) return;
        setSearchValue(value);
    }

    return (
        <ObjectSelect
            // disabled={isLoading}
            rightSection={
                (isLoading || searchValue !== debounced) ?
                    <Loader size={"sm"}/> : null
            }
            onSearchChange={setSearchValueImpl}
            renderOption={renderOption}
            searchable
            {...restProps}
            data={products}
            filter={optionsFilter}
        />
    )
}
export default ProductSelect;
// type ControlledValueProps = {
//     value: ProductSchema;
//     onChange: (value: ProductSchema) => void;
// }
// type RestProps = {
//     defaultValue?: ProductSchema;
//     onChange: (value: ProductSchema) => void;
//     clientId: number;
// }
// type Props = (RestProps & Partial<ControlledValueProps>) & Omit<SelectProps, 'value' | 'onChange'>;
//
// const ProductSelect: FC<Props> = (props) => {
//     const isControlled = 'value' in props;
//     const [intertalValue, setInternalValue] = useState<ProductSchema | undefined>(props.defaultValue);
//     const value = isControlled ? props.value : intertalValue
//
//     const {products} = useProductsList({clientId: props.clientId});
//
//
//     const data = useMemo(() => products.reduce((acc, product) => {
//         acc.push({
//             label: product.name,
//             value: product.id.toString()
//         });
//         return acc;
//     }, [] as { label: string, value: string }[]), [products]);
//
//     const handleOnChange = (event: string | null) => {
//         if (!event) return;
//         const product = products.find(product => parseInt(event) == product.id);
//         if (!product) return;
//         if (isControlled) {
//             props.onChange(product);
//             return;
//         }
//         setInternalValue(product);
//     }
//     useEffect(() => {
//         if (isControlled || !intertalValue) return;
//         props.onChange(intertalValue);
//     }, [intertalValue]);
//     const restProps = omit(props, ['clientId'])
//     return (
//         <Select
//             {...restProps}
//             withCheckIcon={false}
//             searchable
//             value={value?.id.toString()}
//             onChange={handleOnChange}
//             data={data}
//         />
//     )
// }
// export default ProductSelect;