import {
  DrawInteraction,
  Map as OlMap,
  OSMSource,
  SelectInteraction,
  TileLayer,
  TranslateInteraction,
  VectorLayer,
  VectorSource,
  View,
} from '@jig-software/react-ol';
import { ScrollArea } from '@mantine/core';
import { Feature, Map } from 'ol';
import { Coordinate } from 'ol/coordinate';
import { altKeyOnly } from 'ol/events/condition';
import { Point, Polygon } from 'ol/geom';
import { Draw as OlDraw, Select } from 'ol/interaction';
import { Vector } from 'ol/source';
import { Fill, Icon, Stroke, Style } from 'ol/style';
import { FC, useEffect, useRef, useState } from 'react';
import plan1 from '../../assets/plan-1.png';
import plan2 from '../../assets/plan-2.png';
import plan3 from '../../assets/plan-3.png';
import plan4 from '../../assets/plan-4.png';
import { Group, Stack } from '../../components';
import { Confirm } from '../../components/Confirm';
import { Dialog } from '../../components/Dialog';
import { Job } from '../../lib/sori';
import { twx } from '../../utils';
import { calculateLongestEdge } from '../../utils/calculateLongestEdge';
import { degreesToRadians } from '../../utils/degreesToRadians';
import { radiansToDegrees } from '../../utils/radiansToDegrees';
import { JobForm } from '../JobRecord/JobForm';
import { SignLibrary } from './SignLibrary';

const style2 = new Style({
  stroke: new Stroke({
    color: 'red', // Color for the progress segment
    width: 1,
  }),
  fill: new Fill({
    color: '#55555555',
  }),
});

enum Action {
  Rectangle = 'rectangle',
  Square = 'square',
  Polygon = 'polygon',
  Move = 'move',
  Submit = 'submit',
  Select = 'select',
}

enum Mode {
  GenMarkingMode = 'genMarkingMode',
  EditMarkingMode = 'editMarkingMode',
  SignMode = 'signMode',
}

type EditorProps = {
  job: Job;
};

export const Editor: FC<EditorProps> = () => {
  const [source, setSource] = useState<Vector | null>(null);
  const drawRef = useRef<OlDraw>(null);
  const mapRef = useRef<Map>(null);
  const selectRef = useRef<Select>(null);
  const [preview, setPreview] = useState(false);
  const [action, setAction] = useState<Action | null>(null);
  const [mode, setMode] = useState<Mode | null>(null);
  const [streetView, setStreetView] = useState(false);
  const [currentRotation, setCurrentRotation] = useState(0);
  const [projectRotation, setProjectRotation] = useState(0);
  const [confirmOpen, setConfirmOpen] = useState(false);
  const [selectedSign, setSelectedSign] = useState('');
  const [saveSuccess] = useState(false);

  const centerCoordinates = [12702704.266171953, 2552576.3410693165]; // 22.352743, 114.107071
  const [open, setOpen] = useState(false);

  useEffect(() => {
    const handleBeforeUnload = (event: BeforeUnloadEvent) => {
      event.preventDefault();
      return '';
    };
    console.log('saveSuccess', saveSuccess);
    if (saveSuccess) {
      window.removeEventListener('beforeunload', handleBeforeUnload);
    } else {
      window.addEventListener('beforeunload', handleBeforeUnload);
    }
    return () => {
      window.removeEventListener('beforeunload', handleBeforeUnload);
    };
  }, [saveSuccess]);

  useEffect(() => {
    mapRef.current?.getView()?.on('change:rotation', () => {
      const rotationInRadians = mapRef.current?.getView()?.getRotation() ?? 0;
      const rotationInDegrees = radiansToDegrees(rotationInRadians);
      setCurrentRotation(Math.round((rotationInDegrees % 360) + 360) % 360);
    });
  }, [currentRotation, action]);

  useEffect(() => {
    const test = async () => {
      const geojson = await fetch(
        '/arcgisData/DTAD_YL_BOX_LINE_FeaturesToJ.geojson',
      );
      const data = await geojson.json();
      console.log('data', data);
    };
    test();
  }, [mode]);

  if (source?.getFeatures().length) {
    console.log('source', source?.getFeatures()[0].getGeometry());
  }

  return (
    <>
      {/* Job Form */}
      <Dialog open={open} onRequestClose={() => setOpen(false)}>
        <JobForm onSubmit={() => {}} />
      </Dialog>
      {/* Confirm */}
      <Confirm
        open={confirmOpen}
        title="Are you sure to generate?"
        message="This action will generate the marking & lock rotation"
        onConfirm={() => {
          setConfirmOpen(false);
          setProjectRotation(currentRotation);
          setMode(null);
        }}
        onCancel={() => {
          setConfirmOpen(false);
        }}
      />
      <div className="h-full w-full flex flex-col bg-zinc-100 text-black">
        <Group className="h-full w-full">
          <Stack className="h-full w-full">
            {/* ToolBar */}
            <Stack className="relative h-full w-full">
              <div className="h-36 w-full overflow-hidden bg-white">
                <ToolBar
                  action={action}
                  setAction={(action) => {
                    setAction((act) => (act === action ? null : action));
                  }}
                  onClickPreview={() => setPreview((prev) => !prev)}
                  preview={preview}
                  mode={mode}
                  setMode={setMode}
                  onClear={() => {
                    source?.removeFeatures(source.getFeatures());
                  }}
                  onDelete={() => {
                    selectRef.current?.getFeatures().forEach((feature) => {
                      source?.removeFeature(feature);
                    });
                  }}
                  onGenerate={() => {
                    setConfirmOpen(true);
                  }}
                  streetView={streetView}
                  onStreetView={() => setStreetView((prev) => !prev)}
                  currentRotation={currentRotation}
                  setCurrentRotation={setCurrentRotation}
                  projectRotation={projectRotation}
                  mapRef={mapRef}
                />
              </div>
              <Stack className="relative h-full w-full">
                <div
                  className={twx(
                    'absolute top-0 left-0 rounded-md shadow-md z-10 w-100 h-full p-0.5',
                    {
                      block: preview,
                      hidden: !preview,
                    },
                  )}
                >
                  <div className="relative h-full w-full flex flex-col gap-2 bg-white p-2 pt-8">
                    <button
                      className="absolute right-1 top-1 rounded-full bg-white text-black/60"
                      onClick={() => {
                        setPreview((prev) => !prev);
                      }}
                    >
                      <div className="i-ant-design-close-circle-outlined h-6 w-6"></div>
                    </button>
                    <ScrollArea className="h-full text-center">
                      <Stack className="gap-4">
                        <div className="relative h-full w-full">
                          <img src={plan1} className="h-full w-full" />
                          <p className="">Plan 1</p>
                        </div>
                        <div className="relative h-full w-full">
                          <img src={plan2} className="h-full w-full" />
                          <p className="">Plan 2</p>
                        </div>
                        <div className="relative h-full w-full">
                          <img src={plan3} className="h-full w-full" />
                          <p className="">Plan 3</p>
                        </div>
                        <div className="relative h-full w-full">
                          <img src={plan4} className="h-full w-full" />
                          <p className="">Plan 4</p>
                        </div>
                      </Stack>
                    </ScrollArea>
                  </div>
                </div>
                <div
                  className={twx(
                    'absolute top-0 left-0 rounded-md shadow-md z-10 h-full p-0.5',
                    {
                      block: mode === Mode.SignMode,
                      hidden: mode !== Mode.SignMode,
                    },
                  )}
                >
                  <div className="relative h-full w-full flex flex-col gap-2 bg-white p-2">
                    <button
                      className="absolute right-1 top-1 rounded-full bg-white text-black/60"
                      onClick={() => {
                        setMode(null);
                      }}
                    >
                      <div className="i-ant-design-close-circle-outlined h-6 w-6" />
                    </button>
                    <SignLibrary
                      onSelect={(sign) => {
                        setSelectedSign(sign.id);
                      }}
                      selectedSign={selectedSign}
                    />
                  </div>
                </div>
                <div
                  className={twx(
                    'absolute right-0 top-0 rounded-md shadow-md z-10 h-full p-0.5 w-200',
                    {
                      block: streetView,
                      hidden: !streetView,
                    },
                  )}
                >
                  <div className="relative h-full w-full flex flex-col gap-2 bg-white p-2">
                    <button
                      className="absolute right-1 top-1 rounded-full bg-white text-black/60"
                      onClick={() => {
                        setStreetView((prev) => !prev);
                      }}
                    >
                      <div className="i-ant-design-close-circle-outlined h-6 w-6" />
                    </button>
                    Street View
                  </div>
                </div>
                <OlMap
                  ref={mapRef}
                  defaultControls={{}}
                  defaultInteractions={{ altShiftDragRotate: true }}
                  className="h-full w-full"
                >
                  <View
                    initial={{
                      zoom: 17,
                      center: centerCoordinates,
                    }}
                  />
                  <TileLayer>
                    <OSMSource />
                  </TileLayer>
                  <VectorLayer style={style2}>
                    <VectorSource ref={setSource} />
                  </VectorLayer>
                  {action === Action.Polygon && (
                    <DrawInteraction
                      ref={drawRef}
                      freehandCondition={altKeyOnly}
                      type={'Polygon'}
                      style={{
                        'circle-radius': 5,
                        'circle-fill-color': 'blue',
                        'stroke-color': 'blue',
                        'stroke-width': 2,
                      }}
                      onDrawEnd={(event) => {
                        const geometry = event?.feature?.getGeometry();
                        if (!geometry || !(geometry instanceof Polygon)) return;
                        const coordinates: Coordinate[][] =
                          geometry.getCoordinates() as unknown as Coordinate[][];

                        const { longestEdgeAngle } =
                          calculateLongestEdge(coordinates);

                        const progressSegment = new Polygon(coordinates);
                        const progressFeature = new Feature(progressSegment);

                        progressFeature.setStyle(
                          new Style({
                            stroke: new Stroke({
                              color: 'red',
                              width: 4,
                            }),
                            fill: new Fill({
                              color: '#55555555',
                            }),
                          }),
                        );

                        source?.removeFeature(source.getFeatures()[0]);
                        source!.addFeature(progressFeature);

                        mapRef.current
                          ?.getView()
                          ?.setRotation(Math.abs(longestEdgeAngle));
                      }}
                    />
                  )}
                  {action === Action.Rectangle && (
                    <DrawInteraction
                      ref={drawRef}
                      freehandCondition={altKeyOnly}
                      type={'Point'}
                      style={{
                        'circle-radius': 5,
                        'circle-fill-color': 'blue',
                        'stroke-color': 'blue',
                        'stroke-width': 2,
                      }}
                      onDrawEnd={(event) => {
                        const geometry = event?.feature?.getGeometry();
                        const [x, y] = geometry?.getExtent() as [
                          number,
                          number,
                        ];
                        const coordinates: Coordinate[][] = [
                          [
                            [x, y],
                            [x + 200, y],
                            [x + 200, y - 100],
                            [x, y - 100],
                            [x, y],
                          ],
                        ] as Coordinate[][];

                        // 计算旋转后的坐标
                        const rotatedCoordinates = coordinates[0].map(
                          ([coordX, coordY]) => {
                            const angle = degreesToRadians(currentRotation); // 使用当前旋转角度
                            const cos = Math.cos(angle);
                            const sin = Math.sin(angle);
                            return [
                              cos * (coordX - x) - sin * (coordY - y) + x,
                              sin * (coordX - x) + cos * (coordY - y) + y,
                            ];
                          },
                        );

                        const progressSegment = new Polygon([
                          rotatedCoordinates,
                        ]);
                        const progressFeature = new Feature(progressSegment);
                        progressFeature.setStyle(
                          new Style({
                            stroke: new Stroke({
                              color: '#3366ff',
                              width: 2,
                            }),
                            fill: new Fill({
                              color: '#3366ff33',
                            }),
                          }),
                        );

                        source!.addFeature(progressFeature);
                      }}
                    />
                  )}
                  {mode === Mode.SignMode && (
                    <DrawInteraction
                      ref={drawRef}
                      freehandCondition={altKeyOnly}
                      type={'Point'}
                      style={{
                        'circle-radius': 5,
                        'circle-fill-color': 'blue',
                        'stroke-color': 'blue',
                        'stroke-width': 2,
                      }}
                      onDrawEnd={(event) => {
                        const geometry = event?.feature?.getGeometry();
                        const [x, y] = geometry?.getExtent() as [
                          number,
                          number,
                        ];

                        const progressSegment = new Point([x, y]);
                        const progressFeature = new Feature(progressSegment);
                        progressFeature.setStyle(
                          new Style({
                            image: new Icon({
                              src: 'assets/shadow-vehicle.png',
                              color: 'red',
                              scale: 0.1,
                            }),
                          }),
                        );

                        source!.addFeature(progressFeature);
                      }}
                    />
                  )}
                  {action === Action.Select && (
                    <SelectInteraction
                      ref={selectRef}
                      removeCondition={altKeyOnly}
                    />
                  )}
                  {action === Action.Move && <TranslateInteraction />}
                </OlMap>
              </Stack>
            </Stack>
          </Stack>
        </Group>
      </div>
    </>
  );
};

const ToolBar: FC<{
  action: Action | null;
  setAction: (action: Action | null) => void;
  onClickPreview: () => void;
  preview: boolean;
  mode: Mode | null;
  setMode: (mode: Mode | null) => void;
  onClear: () => void;
  onGenerate: () => void;
  onDelete: () => void;
  streetView: boolean;
  onStreetView: () => void;
  currentRotation: number;
  setCurrentRotation: (rotation: number) => void;
  projectRotation: number;
  mapRef: React.RefObject<Map | null>;
}> = ({
  action,
  setAction,
  onClickPreview,
  preview,
  mode,
  setMode,
  onClear,
  onGenerate,
  onDelete,
  streetView,
  onStreetView,
}) => {
  return (
    <div className="h-full flex flex-row gap-2 px-4 py-2.5">
      <ActionButton
        label="Move"
        onClick={() => setAction(Action.Move)}
        active={action === Action.Move}
        icon="i-custom-draw "
      />
      <ActionButton
        label="Select"
        onClick={() => setAction(Action.Select)}
        active={action === Action.Select}
        icon="i-custom-select "
      />
      <ActionButton
        label="Preview"
        onClick={onClickPreview}
        active={preview}
        icon="i-custom-preview "
      />
      <ActionButton
        label="Street View"
        onClick={onStreetView}
        active={streetView}
        icon="i-custom-street-view "
      />
      <div className="m-6 mx-4 border-x-1 border-gray-200" />
      <ActionButton
        label="Generate Marking"
        onClick={() => {
          setMode(mode === Mode.GenMarkingMode ? null : Mode.GenMarkingMode);
          if (mode === Mode.GenMarkingMode) setAction(null);
        }}
        active={mode === Mode.GenMarkingMode}
        icon="i-custom-generate "
      />
      <ActionButton
        label="Edit Marking"
        onClick={() => {
          setMode(mode === Mode.EditMarkingMode ? null : Mode.EditMarkingMode);
          if (mode === Mode.EditMarkingMode) setAction(null);
        }}
        active={mode === Mode.EditMarkingMode}
        icon="i-custom-edit "
      />
      <ActionButton
        label="Sign"
        onClick={() => {
          setMode(mode === Mode.SignMode ? null : Mode.SignMode);
          if (mode === Mode.SignMode) setAction(null);
        }}
        active={mode === Mode.SignMode}
        icon="i-custom-sign-library "
      />
      <div className="m-6 mx-4 border-x-1 border-gray-200" />
      <Group
        className="items-center gap-2.5"
        hidden={mode !== Mode.GenMarkingMode}
      >
        <ActionButton
          label="Area"
          onClick={() => setAction(Action.Polygon)}
          active={action === Action.Polygon}
          icon="i-custom-area "
        />
        <ActionButton
          label="Rectangle"
          onClick={() => setAction(Action.Rectangle)}
          active={action === Action.Rectangle}
          icon="i-custom-rectangle "
        />
      </Group>
      <div
        className="m-6 mx-4 border-x-1 border-gray-200"
        hidden={mode !== Mode.GenMarkingMode && mode !== Mode.SignMode}
      />
      <Group
        className="items-center gap-2.5"
        hidden={mode !== Mode.GenMarkingMode}
      >
        <ActionButton
          label="Generate"
          onClick={onGenerate}
          icon="i-ri-ai-generate "
        />
        <ActionButton
          label="Delete"
          onClick={onDelete}
          icon="i-ant-design-delete-filled "
        />
        <ActionButton
          label="Clear"
          onClick={onClear}
          icon="i-ant-design-clear-outlined "
        />
      </Group>
      <Group className="items-center gap-2.5" hidden={mode !== Mode.SignMode}>
        <ActionButton
          label="Delete"
          onClick={onDelete}
          icon="i-ant-design-delete-filled "
        />
        <ActionButton
          label="Clear"
          onClick={onClear}
          icon="i-ant-design-clear-outlined "
        />
      </Group>
      {/* <div className="flex flex-col border border-black-500 p-2 ml-auto">
        <Stack>
          <Group>
            Current Rotation:
            <input
              type="number"
              className="w-12 bg-white text-black"
              value={currentRotation}
              max={360}
              min={0}
              onChange={(e) => {
                setCurrentRotation(Number(e.target.value));
                mapRef.current
                  ?.getView()
                  ?.setRotation(degreesToRadians(Number(e.target.value)));
              }}
            />
          </Group>
          <Group>
            Project Rotation:
            {projectRotation}
          </Group>
          <Button
            className="bg-white text-black"
            onClick={() => {
              mapRef.current
                ?.getView()
                ?.setRotation(degreesToRadians(projectRotation));
            }}
          >
            Back to Project Rotation
          </Button>
        </Stack>
      </div> */}
    </div>
  );
};

const ActionButton: FC<{
  onClick: () => void;
  active?: boolean;
  className?: string;
  label?: string;
  icon?: string;
  iconClass?: string;
  src?: string;
}> = ({ onClick, className, active, label, icon, iconClass, src }) => {
  return (
    <button
      className={twx(
        ' text-white p-2 text-sm gap-1 flex flex-col items-center  px-4 rounded-md hover:bg-gray-100 max-w-20',
        active ? 'bg-gray-200 text-black/90' : 'bg-white text-black/75',
        className,
      )}
      onClick={onClick}
    >
      {icon && <div className={twx([icon, 'w-12 h-12 shrink-0', iconClass])} />}
      {src && <img src={src} className="h-12 w-12" />}
      <div className="flex basis-10 items-center justify-center text-xs">
        {label}
      </div>
    </button>
  );
};
