import { useMemo, FC, Fragment } from 'react';
import { observer } from 'mobx-react';
import { Banner } from '@servicetitan/design-system';
import { provide, useDependencies } from '@servicetitan/react-ioc';

import { Table, TableColumn, selectColumnMenuFilter, TableCellProps } from '../..';

import { TableStore } from './table.store';
import { categories, CategoryCell } from './categories';
import { Product } from '../overview/product';

export const PackageCell: FC<TableCellProps> = ({ dataItem, tdProps }) => (
    <td {...tdProps}>{dataItem?.Package?.PackageName}</td>
);

export const SelectAsyncExample: FC = provide({
    singletons: [TableStore],
})(
    observer(() => {
        const [{ categoryFetcherClean, madeInFetcherClean, tableState }] =
            useDependencies(TableStore);

        const madeInColumnMenu = useMemo(
            () =>
                selectColumnMenuFilter({
                    dataFetcher: madeInFetcherClean,
                    search: true,
                }),
            [madeInFetcherClean]
        );

        const categoryColumnMenu = useMemo(
            () =>
                selectColumnMenuFilter({
                    dataFetcher: categoryFetcherClean,
                    multiple: true,
                    contentMaxHeight: '250px',
                    valueSelector: item => item.CategoryID,
                }),
            [categoryFetcherClean]
        );

        return (
            <Fragment>
                <Banner title="Default filter with async select" className="m-b-2">
                    Async select filter allows to choose one or several option from the list that
                    will be fetched from BE. The list size is not limited, so you can also use
                    search to find desired option.
                    <br />
                    Use it when there can be greater than 20 possible options
                </Banner>
                <Table tableState={tableState} striped={false}>
                    <TableColumn field="ProductID" title="ID" editable={false} width="100px" />
                    <TableColumn field="ProductName" title="Product Name" width="240px" />
                    <TableColumn
                        field="MadeIn"
                        title="Made In (async single-select filter)"
                        columnMenu={madeInColumnMenu}
                    />
                    <TableColumn
                        field="CategoryID"
                        title="Category (async multi-select filter)"
                        columnMenu={categoryColumnMenu}
                        cell={CategoryCell}
                    />
                </Table>
            </Fragment>
        );
    })
);

export const SelectSyncExample: FC = provide({
    singletons: [TableStore],
})(
    observer(() => {
        const [{ madeInOptions, packageOptions, tableState }] = useDependencies(TableStore);

        const madeInColumnMenu = useMemo(
            () =>
                selectColumnMenuFilter({
                    data: madeInOptions,
                    search: {
                        placeholder: 'Search for made-ins',
                        filter: search => item => item.toLowerCase().includes(search),
                    },
                }),
            [madeInOptions]
        );

        const categoryColumnMenu = useMemo(
            () =>
                selectColumnMenuFilter({
                    data: categories,
                    multiple: true,
                    contentMaxHeight: '250px',
                    valueSelector: item => item.CategoryID,
                    renderItem: item => item.CategoryName,
                    search: true,
                }),
            []
        );

        const packageColumnMenu = useMemo(
            () =>
                selectColumnMenuFilter({
                    data: packageOptions,
                    multiple: false,
                    valueSelector: item => item.Id,
                    renderItem: item => item.Name,
                    rowValueSelector: (item: Product['Package']) => item?.PackageId,
                }),
            [packageOptions]
        );

        return (
            <Fragment>
                <Banner title="Default filter with sync select" className="m-b-2">
                    Select filter allows to choose one or multiple option(s) from the provided list.
                    You can pass simple options (string or number) or complex objects
                </Banner>
                <Table tableState={tableState} striped={false}>
                    <TableColumn field="ProductID" title="ID" editable={false} width="100px" />
                    <TableColumn field="ProductName" title="Product Name" width="240px" />
                    <TableColumn
                        field="MadeIn"
                        title="Made In (sync single-select filter)"
                        columnMenu={madeInColumnMenu}
                    />
                    <TableColumn
                        field="CategoryID"
                        title="Category (sync multi-select filter)"
                        columnMenu={categoryColumnMenu}
                        cell={CategoryCell}
                    />
                    <TableColumn
                        field="Package"
                        title="Package (sync single-select filter)"
                        columnMenu={packageColumnMenu}
                        cell={PackageCell}
                    />
                </Table>
            </Fragment>
        );
    })
);
