import * as React from "react";
import {SimpleGrid, Text, Title, Group, Stack, Button, Space, Textarea, Tabs, HoverCard, ActionIcon, Center} from "@mantine/core";

import {PrimitiveRegistry} from "../onion/primitive_delta";
import {mockUuid} from "../onion/test_helpers";

import {newVersionedModel, VersionedModelState} from "./versioned_model";
import {newCorrespondence} from "./correspondence";

export function getDemoCorr() {
  const generateUUID = mockUuid();
  const primitiveRegistry = new PrimitiveRegistry();

  const commonStuff = {generateUUID, primitiveRegistry};

  const as = newVersionedModel({readonly: false, ...commonStuff});
  const cs = newVersionedModel({readonly: false, ...commonStuff});
  const corr = newCorrespondence({cs, as, ...commonStuff});

  // returns functional react component
  return function() {
    const [asState, setAsState] = React.useState<VersionedModelState>(as.initialState);
    const [csState, setCsState] = React.useState<VersionedModelState>(cs.initialState);
    const [corrState, setCorrState] = React.useState<VersionedModelState>(corr.initialState);

    const asReducer = as.getReducer(setAsState);
    const csReducer = cs.getReducer(setCsState);
    const corrReducer = corr.getReducer(setCorrState, csReducer, asReducer);

    const csComponents = cs.getReactComponents(csState, {
      onUserEdit: corrReducer.parse,
      onUndoClicked: csReducer.undo,
      onRedoClicked: csReducer.redo,
      onVersionClicked: csReducer.gotoVersion,
    });
    const corrComponents = corr.getReactComponents(corrState, {
      onUndoClicked: corrReducer.gotoVersion,
      onRedoClicked: corrReducer.gotoVersion,
      onVersionClicked: corrReducer.gotoVersion,
    });
    const asComponents = as.getReactComponents(asState, {
      onUserEdit: corrReducer.render,
      onUndoClicked: asReducer.undo,
      onRedoClicked: asReducer.redo,
      onVersionClicked: asReducer.gotoVersion,
    });

    const csTabs = ["editor", "state", "history", "dependencyL1", "dependencyL0"];
    const corrTabs = ["state", "history", "dependencyL1", "dependencyL0"];
    const asTabs = ["state", "history", "dependencyL1", "dependencyL0"];

    const makeTabs = (components, defaultTab, tabs) => {
      return <Tabs defaultValue={defaultTab} keepMounted={false}>
        <Tabs.List>
          {tabs.map(tab => ({
            editor: <Tabs.Tab key={tab} value={tab}>Editor</Tabs.Tab>,
            state:  <Tabs.Tab key={tab} value={tab}>State</Tabs.Tab>,
            history: <Tabs.Tab key={tab} value={tab}>History</Tabs.Tab>,
            dependencyL1: <Tabs.Tab key={tab} value={tab}>Deltas (L1)</Tabs.Tab>,
            dependencyL0: <Tabs.Tab key={tab} value={tab}>Deltas (L0)</Tabs.Tab>,
          }[tab]))}
        </Tabs.List>
        <Tabs.Panel value="state">
          {components.graphStateComponent}
        </Tabs.Panel>
        <Tabs.Panel value="editor">
          {components.rountangleEditor}
        </Tabs.Panel>
        <Tabs.Panel value="dependencyL1">
          {components.depGraphL1Component}
        </Tabs.Panel>
        <Tabs.Panel value="dependencyL0">
          {components.depGraphL0Component}
        </Tabs.Panel>
        <Tabs.Panel value="history">
          {components.historyComponent}
        </Tabs.Panel>
      </Tabs>;
    }

    return (<>
      <SimpleGrid cols={3}>
        <div>
          <Title order={4}>Concrete Syntax</Title>
          <Stack>
            {makeTabs(csComponents, "editor", csTabs)}
            {makeTabs(csComponents, "history", csTabs)}
          </Stack>
        </div>
        <div>
          <Title order={4}>Correspondence</Title>
          <Stack>
            {makeTabs(corrComponents, "state", corrTabs)}
            {makeTabs(corrComponents, "history", corrTabs)}
          </Stack>
        </div>
        <div>
          <Title order={4}>Abstract Syntax</Title>
          <Stack>
            {makeTabs(asComponents, "state", asTabs)}
            {makeTabs(asComponents, "history", asTabs)}
          </Stack>
        </div>
      </SimpleGrid>
      <Center>{corrComponents.undoRedoButtons}</Center>
    </>);
  }
}
