import React, { useEffect, useRef } from 'react';

import type { SceneGrid } from '../../../shared/types';

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

type Viewport = { x: number; y: number; w: number; h: number };

type Props = {
  grid: SceneGrid | null | undefined;
  viewport: Viewport | null;
};

function drawSquareGrid(
  ctx: CanvasRenderingContext2D,
  w: number,
  h: number,
  cell: number,
): void {
  ctx.beginPath();
  for (let x = 0; x <= w + 0.5; x += cell) {
    ctx.moveTo(x + 0.5, 0);
    ctx.lineTo(x + 0.5, h);
  }
  for (let y = 0; y <= h + 0.5; y += cell) {
    ctx.moveTo(0, y + 0.5);
    ctx.lineTo(w, y + 0.5);
  }
  ctx.stroke();
}

/** Flat-top hex grid; `cell` ≈ ширина гекса (расстояние между параллельными сторонами по X ≈ 0.75·cell между центрами). */
function drawHexGrid(ctx: CanvasRenderingContext2D, w: number, h: number, cell: number): void {
  const hexW = cell;
  const vert = (Math.sqrt(3) / 2) * hexW;
  const horiz = hexW * 0.75;
  const r = hexW / 2;

  ctx.beginPath();
  const cols = Math.ceil(w / horiz) + 2;
  const rows = Math.ceil(h / vert) + 2;
  for (let row = -1; row < rows; row++) {
    for (let col = -1; col < cols; col++) {
      const cx = col * horiz;
      const cy = row * vert + (col % 2 === 0 ? 0 : vert / 2);
      for (let i = 0; i < 6; i++) {
        const a = (Math.PI / 3) * i;
        const x = cx + r * Math.cos(a);
        const y = cy + r * Math.sin(a);
        if (i === 0) ctx.moveTo(x, y);
        else ctx.lineTo(x, y);
      }
      ctx.closePath();
    }
  }
  ctx.stroke();
}

export function SceneGridOverlay({ grid, viewport }: Props) {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas || !viewport || !grid?.enabled) return;
    const dpr = Math.max(1, Math.min(2, window.devicePixelRatio || 1));
    const w = Math.max(1, Math.round(viewport.w));
    const h = Math.max(1, Math.round(viewport.h));
    canvas.width = Math.round(w * dpr);
    canvas.height = Math.round(h * dpr);
    canvas.style.width = `${w}px`;
    canvas.style.height = `${h}px`;

    const ctx = canvas.getContext('2d');
    if (!ctx) return;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    ctx.clearRect(0, 0, w, h);

    const minDim = Math.min(w, h);
    const cell = Math.max(4, grid.sizeN * minDim);
    ctx.strokeStyle = grid.color || '#ffffff';
    ctx.lineWidth = 1;
    ctx.globalAlpha = 0.72;

    if (grid.type === 'hex') {
      drawHexGrid(ctx, w, h, cell);
    } else {
      drawSquareGrid(ctx, w, h, cell);
    }
  }, [
    grid?.enabled,
    grid?.type,
    grid?.sizeN,
    grid?.color,
    viewport?.x,
    viewport?.y,
    viewport?.w,
    viewport?.h,
  ]);

  if (!viewport || !grid?.enabled) return null;

  return (
    <div
      className={styles.layer}
      style={{ left: viewport.x, top: viewport.y, width: viewport.w, height: viewport.h }}
      aria-hidden
    >
      <canvas ref={canvasRef} className={styles.canvas} />
    </div>
  );
}
