import React, { useState } from 'react';

import { createFlatTreeMap, getAggregateSelectedIds } from '@/mui/helpers/treeView';

import Playground from '@/modules/designSystem/modules/Playground/Playground';
import iabResolver from '../../../../graphql/services/configuration/resolvers/iab';
import { Autocomplete, Stack, TextField, TreeView } from '@/mui/components';

function TreeViewSection() {
  const [search, setSearch] = useState('');
  const [flatTree, setFlatTree] = useState(
    createFlatTreeMap(iabResolver(), {
      label: 'name',
      children: 'categories',
    }),
  );

  const updateTreeState = (selectedFn) => {
    setFlatTree((prevFlatMap) => {
      const copiedMap = new Map();

      prevFlatMap.forEach((node) => {
        copiedMap.set(node.id, {
          ...node,
          selected: selectedFn(node),
        });
      });

      return copiedMap;
    });
  };

  return (
    <Playground
      title="Regular Tree"
      initialState={[
        {
          type: 'checkbox',
          stateId: 'multiSelect',
          selected: true,
        },
        {
          type: 'checkbox',
          stateId: 'autoSuggest',
          selected: true,
        },
      ]}
      renderCallback={(state) => ({
        component: (
          <Stack direction="column" spacing={4} sx={{ width: '100%' }}>
            <Autocomplete
              size="medium"
              freeSolo
              multiple
              fullWidth
              inputValue={search}
              value={getAggregateSelectedIds(flatTree, state.multiSelect)}
              optionValueKey="id"
              options={[]}
              getOptionLabel={(id) => flatTree.get(id).label}
              onChange={(event, autocompleteValues, reason, value) => {
                if (reason === 'removeOption') {
                  const targetNode = flatTree.get(value.option);

                  updateTreeState(
                    (sourceNode) =>
                      sourceNode.selected &&
                      sourceNode.id !== targetNode.id &&
                      !targetNode.childrenIds.includes(sourceNode.id) &&
                      !targetNode.parentPath.includes(sourceNode.id),
                  );
                } else if (reason === 'clear') {
                  updateTreeState(() => false);
                  setSearch('');
                }
              }}
              onInputChange={(event, value) => setSearch(value)}
              renderInput={(params) => <TextField {...params} />}
            />
            <TreeView
              flatTree={flatTree}
              searchText={search}
              multiSelect={state.multiSelect}
              autoSuggest={state.autoSuggest}
              onNodeSelect={(event, nodeIds) => {
                updateTreeState((sourceNode) => nodeIds.includes(sourceNode.id));
              }}
            />
          </Stack>
        ),
        code: `
const [search, setSearch] = useState('');
const [flatTree, setFlatTree] = useState(createFlatTreeMap(iabResolver(), {
  label: 'name',
  children: 'categories',
}));

const updateTreeState = (selectedFn) => setFlatTree((prevFlatMap) => {
  const copiedMap = new Map();

  prevFlatMap.forEach((node) => {
    copiedMap.set(node.id, {
      ...node,
      selected: selectedFn(node),
    });
  });

  return copiedMap;
});

<Autocomplete
  size="medium"
  freeSolo
  multiple
  fullWidth
  inputValue={search}
  value={getAggregateSelectedIds(flatTree, ${state.multiSelect})}
  optionValueKey="id"
  options={[]}
  getOptionLabel={(id) => flatTree.get(id).label}
  onChange={(event, autocompleteValues, reason, value) => {
    if (reason === 'removeOption') {
      const targetNode = flatTree.get(value.option);

      updateTreeState((sourceNode) => sourceNode.selected && sourceNode.id !== targetNode.id
            && !targetNode.childrenIds.includes(sourceNode.id)
            && !targetNode.parentPath.includes(sourceNode.id));
    } else if (reason === 'clear') {
      updateTreeState(() => false);
      setSearch('');
    }
  }}
  onInputChange={(event, value) => setSearch(value)}
  renderInput={(params) => <TextField {...params} />}
/>
<TreeView
  flatTree={flatTree}
  searchText={search}
  multiSelect={state.multiSelect}
  autoSuggest={state.autoSuggest}
  onNodeSelect={(event, nodeIds) => {
    updateTreeState((sourceNode) => nodeIds.includes(sourceNode.id));
  }}
/>`,
      })}
    />
  );
}

export default TreeViewSection;
