'use client';

import { useRef, useEffect, useState, useCallback } from 'react';
import { useCanvasStore, useLayerStore } from '@/store';
import { cn } from '@/lib/utils';
import { Maximize2, Minimize2 } from 'lucide-react';

const MINIMAP_MAX_SIZE = 200; // Maximum width/height in pixels

export function MiniMap() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [isExpanded, setIsExpanded] = useState(true);
  const [isDragging, setIsDragging] = useState(false);

  const { width: canvasWidth, height: canvasHeight, zoom, offsetX, offsetY, setZoom, setPanOffset } = useCanvasStore();
  const { layers } = useLayerStore();

  // Calculate minimap dimensions maintaining aspect ratio
  const aspectRatio = canvasWidth / canvasHeight;
  let minimapWidth = MINIMAP_MAX_SIZE;
  let minimapHeight = MINIMAP_MAX_SIZE;

  if (aspectRatio > 1) {
    // Landscape
    minimapHeight = MINIMAP_MAX_SIZE / aspectRatio;
  } else {
    // Portrait
    minimapWidth = MINIMAP_MAX_SIZE * aspectRatio;
  }

  const scale = minimapWidth / canvasWidth;

  // Render minimap
  useEffect(() => {
    if (!canvasRef.current || !isExpanded) return;

    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    // Set canvas size
    canvas.width = minimapWidth;
    canvas.height = minimapHeight;

    // Clear canvas
    ctx.clearRect(0, 0, minimapWidth, minimapHeight);

    // Draw checkerboard background
    const checkSize = 4;
    ctx.fillStyle = '#ffffff';
    ctx.fillRect(0, 0, minimapWidth, minimapHeight);
    ctx.fillStyle = '#e0e0e0';
    for (let y = 0; y < minimapHeight; y += checkSize) {
      for (let x = 0; x < minimapWidth; x += checkSize) {
        if ((x / checkSize + y / checkSize) % 2 === 0) {
          ctx.fillRect(x, y, checkSize, checkSize);
        }
      }
    }

    // Draw all visible layers (scaled down)
    ctx.save();
    ctx.scale(scale, scale);

    layers
      .filter((layer) => layer.visible && layer.canvas)
      .sort((a, b) => a.order - b.order) // Bottom to top
      .forEach((layer) => {
        if (!layer.canvas) return;
        ctx.globalAlpha = layer.opacity;
        ctx.drawImage(layer.canvas, layer.x, layer.y);
      });

    ctx.restore();

    // Draw viewport indicator
    const viewportWidth = window.innerWidth - 344; // Approximate viewport width
    const viewportHeight = window.innerHeight - 138; // Approximate viewport height

    const visibleCanvasWidth = viewportWidth / zoom;
    const visibleCanvasHeight = viewportHeight / zoom;

    const viewportX = (-offsetX / zoom) * scale;
    const viewportY = (-offsetY / zoom) * scale;
    const viewportW = visibleCanvasWidth * scale;
    const viewportH = visibleCanvasHeight * scale;

    // Draw viewport rectangle
    ctx.strokeStyle = '#3b82f6'; // Primary blue
    ctx.lineWidth = 2;
    ctx.strokeRect(viewportX, viewportY, viewportW, viewportH);

    // Draw semi-transparent fill
    ctx.fillStyle = 'rgba(59, 130, 246, 0.1)';
    ctx.fillRect(viewportX, viewportY, viewportW, viewportH);
  }, [layers, zoom, offsetX, offsetY, minimapWidth, minimapHeight, scale, isExpanded]);

  // Handle click/drag to change viewport
  const handlePointerDown = useCallback((e: React.PointerEvent) => {
    if (!canvasRef.current) return;
    setIsDragging(true);

    const rect = canvasRef.current.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    // Convert minimap coordinates to canvas coordinates
    const canvasX = x / scale;
    const canvasY = y / scale;

    // Center the viewport on the clicked point
    const newOffsetX = -canvasX * zoom + (window.innerWidth - 344) / 2;
    const newOffsetY = -canvasY * zoom + (window.innerHeight - 138) / 2;

    setPanOffset(newOffsetX, newOffsetY);
  }, [scale, zoom, setPanOffset]);

  const handlePointerMove = useCallback((e: React.PointerEvent) => {
    if (!isDragging || !canvasRef.current) return;

    const rect = canvasRef.current.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    const canvasX = x / scale;
    const canvasY = y / scale;

    const newOffsetX = -canvasX * zoom + (window.innerWidth - 344) / 2;
    const newOffsetY = -canvasY * zoom + (window.innerHeight - 138) / 2;

    setPanOffset(newOffsetX, newOffsetY);
  }, [isDragging, scale, zoom, setPanOffset]);

  const handlePointerUp = useCallback(() => {
    setIsDragging(false);
  }, []);

  if (!isExpanded) {
    return (
      <div
        ref={containerRef}
        className="absolute bottom-4 right-4 z-10 bg-card border border-border rounded-md shadow-lg"
      >
        <button
          onClick={() => setIsExpanded(true)}
          className="p-2 hover:bg-accent rounded-md transition-colors"
          title="Show Navigator"
        >
          <Maximize2 className="h-4 w-4" />
        </button>
      </div>
    );
  }

  return (
    <div
      ref={containerRef}
      className="absolute bottom-4 right-4 z-10 bg-card border border-border rounded-md shadow-lg p-2 flex flex-col gap-2"
    >
      {/* Header */}
      <div className="flex items-center justify-between">
        <span className="text-xs font-medium text-muted-foreground">Navigator</span>
        <button
          onClick={() => setIsExpanded(false)}
          className="p-1 hover:bg-accent rounded transition-colors"
          title="Hide Navigator"
        >
          <Minimize2 className="h-3 w-3" />
        </button>
      </div>

      {/* Mini-map canvas */}
      <canvas
        ref={canvasRef}
        className={cn(
          'border border-border rounded cursor-pointer',
          isDragging && 'cursor-grabbing'
        )}
        style={{
          width: `${minimapWidth}px`,
          height: `${minimapHeight}px`,
        }}
        onPointerDown={handlePointerDown}
        onPointerMove={handlePointerMove}
        onPointerUp={handlePointerUp}
        onPointerLeave={handlePointerUp}
      />

      {/* Zoom indicator */}
      <div className="text-xs text-center text-muted-foreground font-mono">
        {Math.round(zoom * 100)}%
      </div>
    </div>
  );
}
