import { Component, SyntheticEvent, ReactNode, FC } from 'react';

import { IdType } from '@servicetitan/data-query';
import { TableFilterCellProps, Radio } from '@servicetitan/design-system';

import {
    CustomColumnMenuFilterSingleOpts,
    renderCustomColumnMenuFilter,
} from '../column-menu-filters';

interface SelectorProps<TV, TO> {
    options: TO[];
    value?: TV;
    valueSelector(item: TO): TV;
    onChange(value: TV | undefined, event: SyntheticEvent<HTMLInputElement>): void;
    renderer?(item: TO): ReactNode;
}

class SelectorRadio<TV, TO> extends Component<SelectorProps<TV, TO>> {
    render() {
        const { options, value, renderer } = this.props;

        return options.map((option, index) => {
            const optionValue = this.props.valueSelector(option);
            return (
                // eslint-disable-next-line react/no-array-index-key
                <span key={index} className="k-widget m-b-1-i d-b">
                    <Radio
                        label={renderer ? renderer(option) : `${option}`}
                        checked={value === optionValue}
                        onChange={(_, event) => this.props.onChange(optionValue, event)}
                    />
                </span>
            );
        });
    }
}

export interface SingleSelectColumnMenuOptions<
    TV,
    TO = TV,
> extends CustomColumnMenuFilterSingleOpts {
    options: TO[];
    valueSelector?: (item: TO) => TV;
    renderItem?: (item: TO) => ReactNode | string;
    filterOperator?: (listItem: any, value: TV) => boolean;
}

export function singleSelectColumnMenuFilter<TV extends IdType, TO = TV>({
    options,
    valueSelector,
    renderItem,
    filterOperator,
    ...opts
}: SingleSelectColumnMenuOptions<TV, TO>) {
    const FilterCell: FC<TableFilterCellProps> = ({ value, onChange }) => {
        const handleChange = (value: TV | undefined, event: SyntheticEvent<HTMLInputElement>) => {
            const filter =
                value === undefined
                    ? { value: '', operator: '' }
                    : {
                          value,
                          operator: filterOperator ?? 'equals',
                      };

            onChange({
                ...filter,
                syntheticEvent: event,
            });
        };

        return (
            <SelectorRadio
                options={options}
                value={value === '' ? undefined : value}
                onChange={handleChange}
                renderer={renderItem}
                valueSelector={valueSelector ?? (option => option)}
            />
        );
    };

    return renderCustomColumnMenuFilter(FilterCell, opts);
}
