import {useRef, useState} from 'react';

import {useEcs} from '@/context/ecs.js';

import styles from './devtools.module.css';

export default function Devtools({
  brush,
  layer,
  setBrush,
  setLayer,
  setStamp,
}) {
  const offsetRef = useRef();
  const [selection, setSelection] = useState({x: 0, y: 0, w: 2, h: 2});
  const [moveStart, setMoveStart] = useState();
  const [ecs] = useEcs();
  if (!ecs) {
    return false;
  }
  const master = ecs.get(1);
  if (!master) {
    return false;
  }
  const {TileLayers} = master;
  const {sourceJson, tileSize} = TileLayers.layer(0);
  const {w, h} = sourceJson.meta.size;
  return (
    <div className={styles.devtools}>
      <form>
        <div className={styles.topBar}>
          <div className={styles.layer}>
            <label>
              Layer:
              <select
                onChange={(event) => {
                  setLayer(event.target.value)
                }}
                value={layer}
              >
                {
                  Object.keys(TileLayers.layers)
                    .map((layer, i) => (
                      <option
                        key={i}
                        value={i}
                      >
                        {i}
                      </option>
                    ))
                }
              </select>
            </label>
          </div>
          <div className={styles.brush}>
            <label>
              Brush:
              <select
                onChange={(event) => {
                  setLayer(event.target.value)
                }}
                value={brush}
              >
                <option>Paint</option>
              </select>
            </label>
          </div>
       </div>
      </form>
      {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
      <div
        onMouseDown={(event) => {
          if (!offsetRef.current) {
            return;
          }
          const {left, top} = offsetRef.current.getBoundingClientRect();
          const x = Math.floor((event.clientX - left) / tileSize.x);
          const y = Math.floor((event.clientY - top) / tileSize.y);
          setMoveStart({x, y});
          setSelection({x, y, w: 1, h: 1});
        }}
        onMouseMove={(event) => {
          if (!offsetRef.current) {
            return;
          }
          if (!moveStart) {
            return;
          }
          const {x: sx, y: sy} = moveStart;
          const {left, top} = offsetRef.current.getBoundingClientRect();
          const x = Math.floor(
            Math.max(0, Math.min(w - 1, (event.clientX - left)) / tileSize.x),
          );
          const y = Math.floor(
            Math.max(0, Math.min(h - 1, (event.clientY - top)) / tileSize.y),
          );
          const mx = Math.min(sx, x);
          const my = Math.min(sy, y);
          setSelection({x: mx, y: my, w: Math.abs(sx - x) + 1, h: Math.abs(sy - y) + 1});
        }}
        onMouseUp={() => {
          setMoveStart();
          const stamp = [];
          const {x, y, w: sw, h: sh} = selection;
          const tw = w / tileSize.x;
          for (let iy = 0; iy < sh; ++iy) {
            const row = [];
            for (let ix = 0; ix < sw; ++ix) {
              row.push((y + iy) * tw + x + ix);
            }
            stamp.push(row);
          }
          setStamp(stamp);
        }}
        className={styles.selectionWrapper}
        ref={offsetRef}
      >
        <div
          className={styles.selection}
          style={{
            top: selection.y * tileSize.y,
            left: selection.x * tileSize.x,
            height: selection.h * tileSize.x,
            width: selection.w * tileSize.y,
          }}
        />
        <img
          alt="tileset"
          src={TileLayers.layer(0).source.replace('.json', '.png')}
        />
      </div>
   </div>
  );
}