import * as React from "react";

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;
`;

export enum modes {
	DRAW_LINE_STRING = "draw_line_string",
	DRAW_POLYGON = "draw_polygon",
	DRAW_POINT = "draw_point",
	DRAW_RECTANGLE = "draw_rectangle",
	DRAW_CIRCLE = "draw_circle",
	SIMPLE_SELECT = "simple_select",
	DIRECT_SELECT = "direct_select",
	MEASURE_DISTANCE = "measure_distance",
	MEASURE_ANGLE = "measure_angle",
	MEASURE_AREA = "measure_area",
	STATIC = "static",
}

const Button = styled.button<{ active?: boolean; kind?: string }>`
  color: #fff;
  background: ${({ kind, active }) =>
		kind === "danger"
			? "rgb(180, 40, 40)"
			: active
			? "rgb(30, 60, 80)"
			: "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(30, 60, 80);
  }
`;

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: modes;
	modeConfig: any;
	geoJson: any;
	onSetMode: (mode: modes) => 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: modes.STATIC,
				content: <Icon name="pointer" />,
				id: "viewMode",
				title: "Pointer",
			},
		],
	},
	{
		modes: [
			{
				mode: modes.DRAW_POINT,
				content: <Icon name="map-pin" />,
				id: "drawPointMode",
				title: "Teken Punt",
			},
		],
	},
	{
		modes: [
			{
				mode: modes.DRAW_LINE_STRING,
				content: <Icon name="stats" />,
				id: "drawLineMode",
				title: "Teken Lijn",
			},
		],
	},
	{
		modes: [
			{
				mode: modes.DRAW_POLYGON,
				content: <Icon name="shape-polygon" />,
				id: "drawPolygonMode",
				title: "Teken Polygoon",
			},
			{
				mode: modes.DRAW_RECTANGLE,
				content: <Icon name="rectangle" />,
				id: "drawRectangleMode",
				title: "Teken Rechthoek",
			},
			{
				mode: modes.DRAW_CIRCLE,
				content: <Icon name="circle" />,
				id: "drawCircleMode",
				title: "Teken Cirkel",
			},
		],
	},
	{
		modes: [
			{
				mode: modes.MEASURE_DISTANCE,
				content: <Icon name="ruler" />,
				id: "measureDistanceMode",
			},
			{
				mode: modes.MEASURE_ANGLE,
				content: <Icon name="shape-triangle" />,
				id: "measureAngleMode",
			},
			{
				mode: modes.MEASURE_AREA,
				content: <Icon name="shape-square" />,
				id: "measureAreaMode",
			},
		],
	},
	{
		modes: [
			{
				mode: modes.SIMPLE_SELECT,
				content: <Icon name="edit" />,
				id: "editMode",
				title: "Bewerk",
			},
		],
	},
];

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}
			title={buttonConfig.title}
		>
			{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 DrawToolbox({
	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={JSON.stringify(modeGroup)}
						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)} />
			)}
		</>
	);
}
