import React, { FC, MouseEventHandler, useMemo } from 'react';

interface MiniMapOverlayProps {
  visible: boolean;
  position: { x: number; y: number };
  isDragging: boolean;
  onMouseDown: MouseEventHandler<HTMLDivElement>;
  onClose: () => void;
  visitedRooms: Record<string, unknown>;
  currentRoom: { x: number; y: number };
  onTravel: (x: number, y: number) => void;
}

interface MiniMapCell {
  x: number;
  y: number;
  explored: boolean;
  isCurrent: boolean;
}

const MiniMapOverlay: FC<MiniMapOverlayProps> = ({
  visible,
  position,
  isDragging,
  onMouseDown,
  onClose,
  visitedRooms,
  currentRoom,
  onTravel,
}) => {
  const exploredRooms = useMemo(() => {
    const entries = Object.keys(visitedRooms || {}).map((key) => {
      const [x, y] = key.split(',').map(Number);
      return { x, y, key };
    });

    const currentKey = `${currentRoom.x},${currentRoom.y}`;
    if (!entries.some((entry) => entry.key === currentKey)) {
      entries.push({ x: currentRoom.x, y: currentRoom.y, key: currentKey });
    }

    return entries;
  }, [visitedRooms, currentRoom.x, currentRoom.y]);

  const gridData = useMemo(() => {
    if (exploredRooms.length === 0) {
      return { cells: [], columns: 0, exploredCount: 0 };
    }

    const xs = exploredRooms.map((room) => room.x);
    const ys = exploredRooms.map((room) => room.y);
    const minX = Math.min(...xs);
    const maxX = Math.max(...xs);
    const minY = Math.min(...ys);
    const maxY = Math.max(...ys);

    const cells: MiniMapCell[] = [];
    for (let y = minY; y <= maxY; y += 1) {
      for (let x = minX; x <= maxX; x += 1) {
        const explored = exploredRooms.some((room) => room.x === x && room.y === y);
        cells.push({
          x,
          y,
          explored,
          isCurrent: x === currentRoom.x && y === currentRoom.y,
        });
      }
    }

    return {
      cells,
      columns: maxX - minX + 1,
      exploredCount: exploredRooms.length,
    };
  }, [exploredRooms, currentRoom.x, currentRoom.y]);

  if (!visible) {
    return null;
  }

  return (
    <div
      className="draggable-modal mini-map-panel"
      style={{
        left: `${position.x}px`,
        top: `${position.y}px`,
        cursor: isDragging ? 'grabbing' : 'grab',
      }}
      onMouseDown={onMouseDown}
    >
      <div className="modal-header">
        <h3>🗺️ World Map</h3>
        <button
          type="button"
          className="modal-close-btn"
          onClick={(event) => {
            event.stopPropagation();
            onClose();
          }}
        >
          ✕
        </button>
      </div>
      <div className="modal-content">
        <p className="panel-description">
          Click on any explored room to travel there instantly
        </p>
        <div className="mini-map-container">
          <div
            className="mini-map-grid"
            style={{ gridTemplateColumns: `repeat(${gridData.columns}, 1fr)`, width: '100%' }}
          >
            {gridData.cells.map((cell, index) => (
              <div
                key={`${cell.x},${cell.y}`}
                className={`mini-map-cell${cell.explored ? ' explored' : ''}${cell.isCurrent ? ' current' : ''}`}
                onClick={(event) => {
                  event.stopPropagation();
                  if (cell.explored && !cell.isCurrent) {
                    onTravel(cell.x, cell.y);
                  }
                }}
                title={
                  cell.explored
                    ? `Room (${cell.x}, ${cell.y})${cell.isCurrent ? ' - Current' : ' - Click to travel'}`
                    : 'Unexplored'
                }
              >
                {cell.isCurrent ? '📍' : cell.explored ? '✓' : ''}
              </div>
            ))}
          </div>
        </div>
        <div className="mini-map-info">
          <p>
            <strong>Current Room:</strong> ({currentRoom.x}, {currentRoom.y})
          </p>
          <p>
            <strong>Explored:</strong> {gridData.exploredCount} rooms
          </p>
        </div>
      </div>
    </div>
  );
};

export default MiniMapOverlay;


