import { IonContent } from '@ionic/react';
import react, { useState } from 'react';

import './Map.css';
import MouseHandler from './MouseHandler';
import SlippyBoard from './SlippyBoard';
import SingleTouchHandler from './SingleTouchHandler';
import DoubleTouchHandler from './DoubleTouchHandler';
import TiledLayersStack from './TiledLayersStack';

export interface TileKey {
  provider: string;
  zoomLevel: number;
  x: number;
  y: number;
}

interface MapProperties {
  height: number;
  width: number;
}

export const tileKeyToString = (tileKey: TileKey) => {
  return `${tileKey.provider}/${tileKey.zoomLevel}/${tileKey.x}/${tileKey.y}`;
};

const Map: react.FC<MapProperties> = (props: MapProperties) => {
  const nbTiles =
    Math.ceil((Math.max(props.width, props.height) * 2) / 256) + 2;
  const boardSize = nbTiles * 256;

  const [shift, setShift] = useState({ x: -boardSize / 2, y: -boardSize / 2 });
  const [zoom, setZoom] = useState(1);

  const addShift = (deltaShift: { x: number; y: number }) => {
    setShift({ x: shift.x + deltaShift.x, y: shift.y + deltaShift.y });
  };

  const addZoom = (
    zoomFactor: number,
    center: { x: number; y: number },
    deltaShift: { x: number; y: number } = { x: 0, y: 0 }
  ) => {
    addShift({
      x: (shift.x - center.x) * (zoomFactor - 1) + deltaShift.x,
      y: (shift.y - center.y) * (zoomFactor - 1) + deltaShift.y,
    });
    setZoom(zoom * zoomFactor);
  };

  console.log(`Rendering Map, zoom:${zoom}, shift:${JSON.stringify(shift)}`);

  return (
    <IonContent fullscreen={true}>
      <div
        className='map'
        style={{ width: props.width + 'px', height: props.height + 'px' }}
      >
        <MouseHandler
          shift={shift}
          addShift={addShift}
          zoom={zoom}
          addZoom={addZoom}
          boardSize={boardSize}
        >
          <SingleTouchHandler
            shift={shift}
            addShift={addShift}
            zoom={zoom}
            addZoom={addZoom}
            boardSize={boardSize}
          >
            <DoubleTouchHandler
              shift={shift}
              addShift={addShift}
              zoom={zoom}
              addZoom={addZoom}
              boardSize={boardSize}
            />
          </SingleTouchHandler>
        </MouseHandler>
        <SlippyBoard boardSize={boardSize} shift={shift} zoom={zoom}>
          <>
            <rect
              key='background'
              x='0'
              y='0'
              width={boardSize}
              height={boardSize}
              fill='red'
            />
            <TiledLayersStack
              height={props.height}
              width={props.width}
              shift={shift}
              zoom={zoom}
              tileSize={256}
              numberOfZoomLevels={5}
            />
            <circle key='circle' cx='50' cy='50' r='50' />,
          </>
        </SlippyBoard>
      </div>
    </IonContent>
  );
};

export default Map;
