import { ComponentType, SyntheticEvent, FC, MouseEvent } from 'react';
import {
    TableCellProps,
    TableHeaderCellProps,
    Checkbox,
    CheckboxProps,
} from '@servicetitan/design-system';
import classNames from 'classnames';
import * as Styles from './select-cell.module.css';
import { useTdProps } from '../utils/use-td-props';

export type SelectionControlType = ComponentType<CheckboxProps<never>>;

interface SelectColumnCellProps extends TableCellProps {
    isRowSelectable?: boolean;
    control?: SelectionControlType;
}

interface SelectHeaderCellProps extends TableHeaderCellProps {
    isSomeRowsSelected?: boolean;
    control?: SelectionControlType;
}

interface SelectCellProps {
    checked: boolean;
    disabled?: boolean;
    indeterminate?: boolean;
    selectionChange?: (event: { syntheticEvent: SyntheticEvent<any> }) => void;
    control?: SelectionControlType;
}

export const SelectCell: FC<SelectCellProps> = ({
    selectionChange,
    control: Control = Checkbox,
    ...props
}: SelectCellProps) => {
    const onChange = (_0: never, _1: boolean, event: SyntheticEvent<HTMLInputElement>) => {
        if (!selectionChange) {
            return;
        }
        selectionChange({ syntheticEvent: event });
    };

    return <Control className={Styles.checkbox} onChange={onChange} {...props} />;
};

const stopPropagation = (e: MouseEvent<HTMLTableCellElement>) => e.stopPropagation();
export const SelectColumnCell: FC<SelectColumnCellProps> = (props: SelectColumnCellProps) => {
    const tdProps = useTdProps(props);

    if (props.rowType === 'groupHeader') {
        return null;
    }

    if (props.rowType === 'groupFooter') {
        return <td {...tdProps} />;
    }

    return (
        <td
            style={props.style}
            // prevent onRowClick when user misses row selection
            onClick={stopPropagation}
            className={classNames(props.className, 'cursor-default-i')}
            {...tdProps}
        >
            <SelectCell
                checked={props.dataItem.selected}
                disabled={!props.isRowSelectable}
                selectionChange={props.selectionChange}
                indeterminate={props.dataItem.indeterminate}
                control={props.control}
            />
        </td>
    );
};

export const SelectHeaderCell: FC<SelectHeaderCellProps> = (props: SelectHeaderCellProps) => (
    <SelectCell
        checked={props.selectionValue}
        indeterminate={props.isSomeRowsSelected}
        selectionChange={props.selectionChange}
        control={props.control}
    />
);
