import {BaseEnumListSchema, type CancelablePromise} from "../../../client";
import {FC, useEffect, useMemo, useState} from "react";
import {useQuery} from "@tanstack/react-query";
import {Select, SelectProps} from "@mantine/core";
import {omit} from "lodash";

type ControlledValueProps = {
    value: number,
    onChange: (value: number) => void;
}


type RestProps = {
    defaultValue?: number;
    onChange: (value: number) => void;
    fetchFn: () => CancelablePromise<BaseEnumListSchema>;
    queryKey: string;
}
export type BaseEnumSelectProps =
    (RestProps & Partial<ControlledValueProps>)
    & Omit<SelectProps, 'value' | 'onChange' | 'data' | 'defaultValue'>;

export type EnumSelectProps = Omit<BaseEnumSelectProps, 'fetchFn' | 'queryKey'>;

const BaseEnumSelect: FC<BaseEnumSelectProps> = (props: BaseEnumSelectProps) => {
    const {data: queryData = []} = useQuery({
        queryKey: [props.queryKey],
        queryFn: props.fetchFn,
        select: data => data.items || []
    })
    const isControlled = 'value' in props;
    const [internalValue, setInternalValue] = useState<number | undefined>(props.defaultValue);
    const value = isControlled ? props.value : internalValue;
    const selectData = useMemo(() => queryData.reduce((acc, item) => {
        acc.push({
            label: item.name,
            value: item.id.toString()
        });
        return acc;
    }, [] as { label: string, value: string }[]), [queryData]);
    const handleOnChange = (event: string | null) => {
        if (typeof event === 'undefined' || event === null) return;
        const object = queryData.find(item => event == item.id.toString());
        if (!object) return;
        if (isControlled) {
            props.onChange(parseInt(event));
            return;
        }
        setInternalValue(parseInt(event));
    }
    const restProps = omit(props, ['fetchFn', 'queryKey'])
    useEffect(() => {
        if (isControlled || typeof internalValue === 'undefined') return;
        props.onChange(internalValue);
    }, [internalValue]);
    return (
        <Select

            {...restProps}
            defaultValue={props.defaultValue ? props.defaultValue.toString() : undefined}
            value={value?.toString()}
            onChange={handleOnChange}
            data={selectData}
        />
    )
}

export default BaseEnumSelect;