import { ReactElement, useEffect, useState } from 'react';
import FlexViewHeader from './FlexViewHeader';
import { Tag } from '../../db/db';
import { Page, PageFilter, PageSortOrder, fetchAllPages, fetchAllPagesForHumanTag } from '../../db/pages';
import { sortTags, pageToTagSortOrder } from '../sort';
import CollapsibleTag from './pagelists/CollapsibleTag';
import RawPageList from './pagelists/RawPageList';
import TagPageList from './pagelists/TagPageList';
import Inspector from '../inspector/Inspector';
import SplitPane from 'react-split-pane';
import { clearSelectionAndSelectMulti } from '../../store/uiSlice';
import { useLiveQuery } from 'dexie-react-hooks';
import { useAppDispatch } from '../../store/hooks';

interface FlexViewProps {
  singleTag?: Tag;
  tags?: Tag[];
  pages?: Page[];
  defaultGroupByWindow?: boolean;
  defaultSortBy?: PageSortOrder;
  defaultFilter?: PageFilter;
  overrideExpandedTags?: Tag[];
}

const FlexView = ({
  singleTag = undefined,
  tags = [],
  pages = [],
  defaultGroupByWindow = false,
  defaultSortBy = PageSortOrder.recent,
  defaultFilter = { flagged: false },
  overrideExpandedTags = [],
}: FlexViewProps): ReactElement => {
  const [groupByWindow, setGroupByWindow] = useState(defaultGroupByWindow);
  const [sortOrder, setSortOrder] = useState(defaultSortBy);
  const [filter, setFilter] = useState(defaultFilter);

  const shouldFetchAll = pages.length === 0 && tags.length === 0 && singleTag == null;
  const AllPages = useLiveQuery(
    () => (shouldFetchAll ? fetchAllPages() : undefined),
    [shouldFetchAll]
  );
  const dispatch = useAppDispatch();

  // Synchronize inspector size across tabs?  Argh rerenders...
  // const inspectorSize = useAppSelector(selectInspectorSize);

  useEffect(() => {
    // log('Main useEffect keyDownHandler');
    const keyDownHandler = (event: KeyboardEvent) => {
      if (event.key === 'a' && event.metaKey) {
        event.preventDefault();
        dispatch(clearSelectionAndSelectMulti({ urls: pages.map((page) => page.nurl) }));
      }
    };

    document.addEventListener('keydown', keyDownHandler);

    // 👇️ clean up event listener
    return () => {
      document.removeEventListener('keydown', keyDownHandler);
    };
  }, [pages]);

  // Prepare Tags
  const tagsSorted = sortTags(tags, pageToTagSortOrder(sortOrder));
  // Don't pass groupByWindow in to tags, because that'd be annoying?
  const tagList = tagsSorted.map((tag) => (
    <CollapsibleTag
      key={tag.name}
      tag={tag.name}
      sortOrder={sortOrder}
      filter={filter}
      groupByWindow={groupByWindow}
      overrideExpanded={overrideExpandedTags.includes(tag)}
    />
  ));

  const singleTagList = singleTag && (
    <TagPageList
      tag={singleTag?.name}
      sortOrder={sortOrder}
      filter={filter}
      groupByWindow={groupByWindow}
      expanded={true}
    />
  );
  var rawPages: Page[] = pages;

  if (pages.length === 0 && tags.length === 0 && singleTag == null) {
    rawPages = AllPages || [];
  }

  const rawPageList = pages && (
    <RawPageList
      pages={pages}
      sortOrder={sortOrder}
      filter={filter}
      groupByWindow={groupByWindow}
    />
  );

  return (
    /* this lib is incompatible with react18. To fix
     children: React.ReactNode; needs to be added to SplitPaneProps.
     @ts-ignore TS2322 */
    <SplitPane
      allowResize={true}
      split="vertical"
      defaultSize={300} // inspectorSize
      minSize={10}
      primary="second"
      // onDragFinished={(size) => dispatch(setInspectorSize(size))}
    >
      <div className="fill flexContainerHorizontal mainPane">
        <div
          className="flexFillHorizontal"
          style={{
            overflow: 'scroll',
          }}
        >
          {tagList.length > 0 && <div>{tagList}</div>}
          {singleTagList != null && <div>{singleTagList}</div>}

          {tagList.length > 0 && pages.length > 0 && <hr></hr>}

          {rawPageList}
        </div>

        <div
          style={{
            borderLeft: '1px solid',
            borderColor: 'rgb(50, 56, 62)',
            height: '100%',
          }}
        ></div>
      </div>
      <Inspector onSelectAll={async () => {
        let urlsToSelect: string[] = [];
        if (pages.length > 0) {
          urlsToSelect = pages.map((page) => page.nurl.normalized);
        } else if (singleTag) {
          const tagPages = await fetchAllPagesForHumanTag(singleTag.name);
          urlsToSelect = tagPages.map((page) => page.nurl.normalized);
        } else if (tags.length > 0) {
          const allTagPages = await Promise.all(tags.map((t) => fetchAllPagesForHumanTag(t.name)));
          urlsToSelect = [...new Set(allTagPages.flat().map((page) => page.nurl.normalized))];
        } else {
          const all = AllPages || (await fetchAllPages());
          urlsToSelect = all.map((page) => page.nurl.normalized);
        }
        dispatch(
          clearSelectionAndSelectMulti({
            urls: urlsToSelect.map((u) => ({ normalized: u } as any)),
          })
        );
      }}>
        <FlexViewHeader
          tagsSorted={tagsSorted}
          sortOrder={sortOrder}
          setSortOrder={setSortOrder}
          filter={filter}
          setFilter={setFilter}
          groupByWindow={groupByWindow}
          setGroupByWindow={setGroupByWindow}
        />
      </Inspector>
    </SplitPane>
  );
};

export default FlexView;
// function dispatch(arg0: any) {
//   throw new Error('Function not implemented.');
// }
