import * as React from "react";
import {
  ViewMode,
  DrawPointMode,
  DrawLineStringMode,
  DrawPolygonMode,
  DrawCircleFromCenterMode,
  DrawRectangleMode,
  MeasureDistanceMode,
  MeasureAngleMode,
  MeasureAreaMode,
  ModifyMode,
  TranslateMode
} from "@nebula.gl/edit-modes";
import styled from "styled-components";
import { Icon } from "./icon";

import { ImportModal } from "./import-modal";
import { ExportModal } from "./export-modal";

const Tools = styled.div`
  position: absolute;
  display: flex;
  flex-direction: column;
  top: 40px;
  left: 10px;
`;

const Button = styled.button<{ active?: boolean; kind?: string }>`
  color: #fff;
  background: ${({ kind, active }) => (kind === "danger" ? "rgb(180, 40, 40)" : active ? "rgb(56, 111, 164)" : "rgb(69, 102, 131)")};
  font-size: 1em;
  font-weight: 400;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
    "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  border: 1px solid transparent;
  border-radius: 0.25em;
  margin: 0.05em;
  padding: 0.1em 0.2em;
  :hover {
    background: rgb(56, 111, 164);
  }
`;

const SubToolsContainer = styled.div`
  position: relative;
`;

const SubTools = styled.div`
  display: flex;
  flex-direction: row-reverse;
  position: absolute;
  top: 0;
  left: 0;
`;

export interface ToolboxOptions {
  viewModeEnabled?: boolean,

  drawPointModeEnabled?: boolean,

  drawLineModeEnabled?: boolean,

  drawPolygonModeEnabled?: boolean,
  drawRectangleModeEnabled?: boolean,
  drawCircleModeEnabled?: boolean,

  measureDistanceModeEnabled?: boolean,
  measureAngleModeEnabled?: boolean,
  measureAreaModeEnabled?: boolean,

  editModeEnabled?: boolean,
  moveModeEnabled?: boolean,

  importEnabled?: boolean,
  exportEnabled?: boolean,

  settingsModeEnabled?: boolean, // not implemented/tested yet

  deleteEnabled?: boolean,
}

export type Props = {
  mode: any;
  modeConfig: any;
  geoJson: any;
  onSetMode: (mode: any) => unknown;
  onSetModeConfig: (modeConfig: any) => unknown;
  onSetGeoJson: (geojson: any) => unknown;
  onImport: (imported: any) => unknown;
  options?: ToolboxOptions,
};

const defaultToolBoxOptions: ToolboxOptions = {
  viewModeEnabled: true,
  drawPointModeEnabled: true,
  drawLineModeEnabled: true,
  drawPolygonModeEnabled: true,
  drawRectangleModeEnabled: true,
  drawCircleModeEnabled: true,
  measureDistanceModeEnabled: true,
  measureAngleModeEnabled: true,
  measureAreaModeEnabled: true,
  editModeEnabled: true,
  moveModeEnabled: true,
  importEnabled: true,
  exportEnabled: true,
  settingsModeEnabled: false,
  deleteEnabled: true
}

const MODE_GROUPS = [
  {
    modes: [{ mode: ViewMode, content: <Icon name="pointer" />, id: 'viewMode' }]
  },
  {
    modes: [{ mode: DrawPointMode, content: <Icon name="map-pin" />, id: 'drawPointMode', }]
  },
  {
    modes: [
      {
        mode: DrawLineStringMode,
        content: <Icon name="stats" />,
        id: 'drawLineMode'
      }
    ]
  },
  { 
    modes: [
      { mode: DrawPolygonMode, content: <Icon name="shape-polygon" />, id: 'drawPolygonMode' },
      { mode: DrawRectangleMode, content: <Icon name="rectangle" />, id: 'drawRectangleMode' },
      { mode: DrawCircleFromCenterMode, content: <Icon name="circle" />, id: 'drawCircleMode' }
    ]
  },
  {
    modes: [
      { mode: MeasureDistanceMode, content: <Icon name="ruler" />, id: 'measureDistanceMode' },
      { mode: MeasureAngleMode, content: <Icon name="shape-triangle" />, id: 'measureAngleMode' },
      { mode: MeasureAreaMode, content: <Icon name="shape-square" />, id: 'measureAreaMode' }
    ]
  },
  {
    modes: [{ mode: ModifyMode, content: <Icon name="edit" />, id: 'editMode' }]
  },
  {
    modes: [{ mode: TranslateMode, content: <Icon name="move" />, id: 'moveMode' }]
  }
];

const isButtonEnabled = (id:string, options: ToolboxOptions) => !!Object.keys(options).find(key => `${id}Enabled` === key && options[key])

function ModeButton({ buttonConfig, mode, onClick }: any) {
  return (
    <Button active={buttonConfig.mode === mode} onClick={onClick}>
      {buttonConfig.content}
    </Button>
  );
}

function ModeGroupButtons({ modeGroup, mode, onSetMode, options }: any) {
  const useOptions: ToolboxOptions = options;
  const [expanded, setExpanded] = React.useState(false);

  const { modes } = modeGroup;

  const mayShowMainButton = !!modes.find(m => isButtonEnabled(m.id, useOptions));
  if(!mayShowMainButton){
    return null;
  }

  let subTools = null;

  if (expanded) {
    subTools = (
      <SubTools>
        {modes.map((buttonConfig, i) => {
          const mayShowCurrentButton = isButtonEnabled(buttonConfig.id, useOptions);
          if(!mayShowCurrentButton) return true;
          return <ModeButton
            key={i}
            buttonConfig={buttonConfig}
            mode={mode}
            onClick={() => {
              onSetMode(() => buttonConfig.mode);
              setExpanded(false);
            }}
          />
        })}
      </SubTools>
    );
  }

  // Get the button config if it is active otherwise, choose the first valid one that can be shown
  const buttonConfig = modes.find(m => m.mode === mode) || modes.find(m => isButtonEnabled(m.id, useOptions));

  return (
    <SubToolsContainer>
      {subTools}
      <ModeButton
        buttonConfig={buttonConfig}
        mode={mode}
        onClick={() => {
          onSetMode(() => buttonConfig.mode);
          setExpanded(true);
        }}
      />
    </SubToolsContainer>
  );
}

export function Toolbox({
  mode,
  modeConfig,
  geoJson,
  onSetMode,
  onSetModeConfig,
  onSetGeoJson,
  onImport,
  options
}: Props) {
  const [showConfig, setShowConfig] = React.useState(false);
  const [showImport, setShowImport] = React.useState(false);
  const [showExport, setShowExport] = React.useState(false);
  const [showClearConfirmation, setShowClearConfirmation] = React.useState(false);
  const useOptions = { ...defaultToolBoxOptions, ...(options || {}) }; 
  const { settingsModeEnabled, importEnabled, exportEnabled, deleteEnabled } = useOptions;
  return (
    <>
      <Tools>
        {MODE_GROUPS.map((modeGroup, i) => (
          <ModeGroupButtons key={i} modeGroup={modeGroup} mode={mode} onSetMode={onSetMode} options={useOptions} />
        ))}

        {/* <box-icon name='current-location' ></box-icon> */}
        {exportEnabled && <Button onClick={() => setShowExport(true)} title="Export">
          <Icon name="export" />
        </Button>}
        {importEnabled && <Button onClick={() => setShowImport(true)} title="Import">
          <Icon name="import" />
        </Button>}

        {settingsModeEnabled && (
          <SubToolsContainer>
            {showConfig && (
              <SubTools>
                <Button onClick={() => setShowConfig(false)}>
                  <Icon name="chevron-right" />
                </Button>
                <Button
                  onClick={() => onSetModeConfig({ booleanOperation: "difference" })}
                  active={modeConfig && modeConfig.booleanOperation === "difference"}
                >
                  <Icon name="minus-front" />
                </Button>
                <Button
                  onClick={() => onSetModeConfig({ booleanOperation: "union" })}
                  active={modeConfig && modeConfig.booleanOperation === "union"}
                >
                  <Icon name="unite" />
                </Button>
                <Button
                  onClick={() => onSetModeConfig({ booleanOperation: "intersection" })}
                  active={modeConfig && modeConfig.booleanOperation === "intersection"}
                >
                  <Icon name="intersect" />
                </Button>
                {/* <Button onClick={() => setShowConfig(false)}>
                  <Icon name="x" />
                </Button> */}
              </SubTools>
            )}
            <Button onClick={() => setShowConfig(true)}>
              <Icon name="cog" />
            </Button>
          </SubToolsContainer>
        )}

        {deleteEnabled && <SubToolsContainer>
          {showClearConfirmation && (
            <SubTools>
              <Button
                onClick={() => {
                  onSetGeoJson({ type: "FeatureCollection", features: [] });
                  setShowClearConfirmation(false);
                }}
                kind="danger"
                title="Clear all features"
              >
                Clear all features <Icon name="trash" />
              </Button>
              <Button onClick={() => setShowClearConfirmation(false)}>Cancel</Button>
            </SubTools>
          )}
          <Button onClick={() => setShowClearConfirmation(true)} title="Clear">
            <Icon name="trash" />
          </Button>
        </SubToolsContainer>}

        {/* zoom in and out */}
      </Tools>

      {showImport && (
        <ImportModal
          onImport={imported => {
            onImport(imported);
            setShowImport(false);
          }}
          onClose={() => setShowImport(false)}
        />
      )}

      {showExport && <ExportModal geoJson={geoJson} onClose={() => setShowExport(false)} />}
    </>
  );
}
