import { Fragment, FC, memo, useCallback, useState, ChangeEvent } from 'react';
import { provide, useDependencies } from '@servicetitan/react-ioc';
import { observer } from 'mobx-react';

import { Table, TableColumn, TableCellProps } from '../..';
import { TableStore } from './table.store';
import { Supplier } from './product';
import { TableCell } from '@servicetitan/design-system';

const SupplierCell: FC<TableCellProps> = ({ field, dataItem, tdProps }) => (
    <td {...tdProps}>{Supplier[dataItem[field!]]}</td>
);

const columns = [
    { field: 'ProductID', title: 'ID', minWidth: 50 },
    { field: 'ProductName', title: 'Name', minWidth: 200 },
    { field: 'Supplier', title: 'Supplier', minWidth: 200 },
    { field: 'MadeIn', title: 'Made In', minWidth: 200 },
    { field: 'QuantityPerUnit', title: 'Quantity Per Unit', minWidth: 200 },
    { field: 'UnitPrice', title: 'Price', minWidth: 100 },
    { field: 'UnitsInStock', title: 'In stock', minWidth: 100 },
    { field: 'UnitsOnOrder', title: 'On Order', minWidth: 100 },
    { field: 'Discontinued', title: 'Discontinued', minWidth: 100 },
];

interface CheckboxRowProps {
    field: string;
    label: string;
    checked: boolean;
    onChange: (field: string, checked: boolean) => void;
}

const CheckboxRow = memo(({ field, label, checked, onChange }: CheckboxRowProps) => {
    const handleChange = useCallback(
        (event: ChangeEvent<HTMLInputElement>) => {
            onChange(field, event.target.checked);
        },
        [field, onChange]
    );

    return (
        <div>
            <label>
                <input type="checkbox" checked={checked} onChange={handleChange} /> {label}
            </label>
        </div>
    );
});

interface HiddenColumnsProps {
    onChange: (columns: Set<string>) => void;
    checkedColumns: Set<string>;
}

const HiddenColumns = ({ onChange, checkedColumns }: HiddenColumnsProps) => {
    const handleChange = useCallback(
        (field: string, checked: boolean) => {
            const newState = new Set(Array.from(checkedColumns));
            if (checked) {
                newState.add(field);
            } else {
                newState.delete(field);
            }
            onChange(newState);
        },
        [checkedColumns, onChange]
    );
    return (
        <div>
            <span>Select columns to hide</span>
            <div>
                {columns.map(col => (
                    <CheckboxRow
                        key={col.field}
                        field={col.field}
                        label={col.title}
                        onChange={handleChange}
                        checked={checkedColumns.has(col.field)}
                    />
                ))}
            </div>
        </div>
    );
};

const CellProvider = (props: TableCellProps) => {
    if (props.field === 'Supplier') {
        return <SupplierCell {...props} />;
    }
    return <TableCell {...props} />;
};

export const TableColumnHidingExample: FC = provide({
    singletons: [TableStore],
})(
    observer(() => {
        const [{ tableState }] = useDependencies(TableStore);
        const [hiddenColumns, setHiddenColumns] = useState(new Set<string>());

        const handleHiddenColumnsChange = useCallback((columns: Set<string>) => {
            setHiddenColumns(new Set([...columns]));
        }, []);

        return (
            <Fragment>
                <HiddenColumns
                    checkedColumns={hiddenColumns}
                    onChange={handleHiddenColumnsChange}
                />
                <Table tableState={tableState} striped={false}>
                    {columns
                        .filter(col => !hiddenColumns.has(col.field))
                        .map(column => {
                            return (
                                <TableColumn
                                    field={column.field}
                                    title={column.title}
                                    key={column.field}
                                    id={column.field}
                                    cell={CellProvider}
                                />
                            );
                        })}
                </Table>
            </Fragment>
        );
    })
);
