// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { useApplyScrollbarWidth } from "@coreai-ds/react-components";
import { useTableFeatures } from "@coreai-ds/react-components";
import { createTableColumn } from "@coreai-ds/react-components";
import type { PresenceBadgeStatus } from "@coreai-ds/react-components";
import { DocumentRegular } from "@fluentui/react-icons";
import { EditRegular } from "@fluentui/react-icons";
import { FolderRegular } from "@fluentui/react-icons";
import { OpenRegular } from "@fluentui/react-icons";
import { VideoRegular } from "@fluentui/react-icons";
import { DocumentPdfRegular } from "@fluentui/react-icons";
import { PeopleRegular } from "@fluentui/react-icons";
import { useTableSelection } from "@coreai-ds/react-components";
import type { TableRowData as RowStateBase } from "@coreai-ds/react-components";
import * as React from 'react';
import { Table } from "@coreai-ds/react-components";
import { TableHeader } from "@coreai-ds/react-components";
import { TableRow } from "@coreai-ds/react-components";
import { TableSelectionCell } from "@coreai-ds/react-components";
import { TableHeaderCell } from "@coreai-ds/react-components";
import { TableBody } from "@coreai-ds/react-components";
import { FixedSizeList as List } from "react-window";
import type { ListChildComponentProps } from "react-window";
import { TableCell } from "@coreai-ds/react-components";
import { TableCellLayout } from "@coreai-ds/react-components";
import { Avatar } from "@coreai-ds/react-components";

type Item = {
    file: {
        label: string;
        icon: JSXElement;
    };
    author: {
        label: string;
        status: PresenceBadgeStatus;
    };
    lastUpdated: {
        label: string;
        timestamp: number;
    };
    lastUpdate: {
        label: string;
        icon: JSXElement;
    };
};

const columns = [
    createTableColumn<Item>({
        columnId: 'file',
    }),
    createTableColumn<Item>({
        columnId: 'author',
    }),
    createTableColumn<Item>({
        columnId: 'lastUpdated',
    }),
    createTableColumn<Item>({
        columnId: 'lastUpdate',
    }),
];

const baseItems: Item[] = [
    {
        file: { label: 'Meeting notes', icon: <DocumentRegular /> },
        author: { label: 'Max Mustermann', status: 'available' },
        lastUpdated: { label: '7h ago', timestamp: 1 },
        lastUpdate: {
            label: 'You edited this',
            icon: <EditRegular />,
        },
    },
    {
        file: { label: 'Thursday presentation', icon: <FolderRegular /> },
        author: { label: 'Erika Mustermann', status: 'busy' },
        lastUpdated: { label: 'Yesterday at 1:45 PM', timestamp: 2 },
        lastUpdate: {
            label: 'You recently opened this',
            icon: <OpenRegular />,
        },
    },
    {
        file: { label: 'Training recording', icon: <VideoRegular /> },
        author: { label: 'John Doe', status: 'away' },
        lastUpdated: { label: 'Yesterday at 1:45 PM', timestamp: 2 },
        lastUpdate: {
            label: 'You recently opened this',
            icon: <OpenRegular />,
        },
    },
    {
        file: { label: 'Purchase order', icon: <DocumentPdfRegular /> },
        author: { label: 'Jane Doe', status: 'offline' },
        lastUpdated: { label: 'Tue at 9:30 AM', timestamp: 3 },
        lastUpdate: {
            label: 'You shared this in a Teams chat',
            icon: <PeopleRegular />,
        },
    },
];

const items = new Array(1500).fill(0).map((_, i) => baseItems[i % baseItems.length]);

interface TableRowData extends RowStateBase<Item> {
    onClick: (e: React.MouseEvent) => void;
    onKeyDown: (e: React.KeyboardEvent) => void;
    selected: boolean;
    appearance: 'brand' | 'none';
}

interface ReactWindowRenderFnProps extends ListChildComponentProps {
    data: TableRowData[];
}

const RenderRow = ({ index, style, data }: ReactWindowRenderFnProps) => {
    const { item, selected, appearance, onClick, onKeyDown } = data[index];
    return (<TableRow aria-rowindex={index + 2} style={style} key={item.file.label} onKeyDown={onKeyDown} onClick={onClick} appearance={appearance}>
      <TableSelectionCell checked={selected} checkboxIndicator={{ 'aria-label': 'Select row' }}/>
      <TableCell>
        <TableCellLayout media={item.file.icon}>
          <strong>[{index}] </strong>
          {item.file.label}
        </TableCellLayout>
      </TableCell>
      <TableCell>
        <TableCellLayout media={<Avatar aria-label={item.author.label} name={item.author.label} badge={{ status: item.author.status as PresenceBadgeStatus }}/>}>
          {item.author.label}
        </TableCellLayout>
      </TableCell>
      <TableCell>{item.lastUpdated.label}</TableCell>
      <TableCell>
        <TableCellLayout media={item.lastUpdate.icon}>{item.lastUpdate.label}</TableCellLayout>
      </TableCell>
    </TableRow>);
};

export const Virtualization = (): JSXElement => {
    const appliedScrollbarWidthRef = useApplyScrollbarWidth();
    const { getRows, selection: { allRowsSelected, someRowsSelected, toggleAllRows, toggleRow, isRowSelected }, } = useTableFeatures({
        columns,
        items,
    }, [
        useTableSelection({
            selectionMode: 'multiselect',
            defaultSelectedItems: new Set([0, 1]),
        }),
    ]);
    const rows: TableRowData[] = getRows(row => {
        const selected = isRowSelected(row.rowId);
        return {
            ...row,
            onClick: (e: React.MouseEvent) => toggleRow(e, row.rowId),
            onKeyDown: (e: React.KeyboardEvent) => {
                if (e.key === ' ') {
                    e.preventDefault();
                    toggleRow(e, row.rowId);
                }
            },
            selected,
            appearance: selected ? ('brand' as const) : ('none' as const),
        };
    });
    const toggleAllKeydown = React.useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {
        if (e.key === ' ') {
            toggleAllRows(e);
            e.preventDefault();
        }
    }, [toggleAllRows]);
    return (<Table noNativeElements aria-label="Table with selection" aria-rowcount={rows.length} style={{ minWidth: '650px' }}>
      <TableHeader>
        <TableRow aria-rowindex={1}>
          <TableSelectionCell checked={allRowsSelected ? true : someRowsSelected ? 'mixed' : false} onClick={toggleAllRows} onKeyDown={toggleAllKeydown} checkboxIndicator={{ 'aria-label': 'Select all rows' }}/>
          <TableHeaderCell>File</TableHeaderCell>
          <TableHeaderCell>Author</TableHeaderCell>
          <TableHeaderCell>Last updated</TableHeaderCell>
          <TableHeaderCell>Last update</TableHeaderCell>
          {/** Scrollbar alignment for the header */}
          <div role="presentation" ref={appliedScrollbarWidthRef}/>
        </TableRow>
      </TableHeader>
      <TableBody>
        <List height={400} itemCount={items.length} itemSize={45} width="100%" itemData={rows}>
          {RenderRow}
        </List>
      </TableBody>
    </Table>);
};

export default Virtualization;
