import React, { useRef, useEffect, useCallback } from 'react';
import Box from '@mui/material/Box';
import Paper from '@mui/material/Paper';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import {
  ZoomIn as ZoomInIcon,
  ZoomOut as ZoomOutIcon,
  CenterFocusStrong as CenterIcon,
  Fullscreen as FullscreenIcon,
} from '@mui/icons-material';
import { useDispatch, useSelector } from 'react-redux';
import { RootState, AppDispatch } from '../../zeiterfassungStore';
import {
  zoomIn,
  zoomOut,
  resetView,
  setPan,
} from '../../permissionGraphSlice';

interface CanvasMinimapProps {
  containerWidth: number;
  containerHeight: number;
  contentBounds: {
    x1: number;
    y1: number;
    x2: number;
    y2: number;
  };
  onViewportChange?: (x: number, y: number, zoom: number) => void;
  onFitToView?: () => void;
}

const MINIMAP_WIDTH = 180;
const MINIMAP_HEIGHT = 120;

const CanvasMinimap: React.FC<CanvasMinimapProps> = ({
  containerWidth,
  containerHeight,
  contentBounds,
  onViewportChange,
  onFitToView,
}) => {
  const dispatch = useDispatch<AppDispatch>();
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const isDragging = useRef(false);

  const { zoom, panX, panY, showMinimap } = useSelector(
    (state: RootState) => state.permissionGraph
  );

  // Calculate scale factor for minimap
  const contentWidth = Math.max(contentBounds.x2 - contentBounds.x1, 100);
  const contentHeight = Math.max(contentBounds.y2 - contentBounds.y1, 100);
  const scaleX = MINIMAP_WIDTH / contentWidth;
  const scaleY = MINIMAP_HEIGHT / contentHeight;
  const scale = Math.min(scaleX, scaleY) * 0.8; // 80% to add padding

  // Calculate viewport rectangle in minimap coordinates
  const viewportWidth = (containerWidth / zoom) * scale;
  const viewportHeight = (containerHeight / zoom) * scale;
  const viewportX = ((contentBounds.x1 - panX / zoom) * scale) + (MINIMAP_WIDTH - contentWidth * scale) / 2;
  const viewportY = ((contentBounds.y1 - panY / zoom) * scale) + (MINIMAP_HEIGHT - contentHeight * scale) / 2;

  // Draw minimap
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

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

    // Clear canvas
    ctx.fillStyle = '#f5f5f5';
    ctx.fillRect(0, 0, MINIMAP_WIDTH, MINIMAP_HEIGHT);

    // Draw border
    ctx.strokeStyle = '#e0e0e0';
    ctx.lineWidth = 1;
    ctx.strokeRect(0, 0, MINIMAP_WIDTH, MINIMAP_HEIGHT);

    // Draw content area (simplified representation)
    const offsetX = (MINIMAP_WIDTH - contentWidth * scale) / 2;
    const offsetY = (MINIMAP_HEIGHT - contentHeight * scale) / 2;

    ctx.fillStyle = '#e8e8e8';
    ctx.fillRect(
      offsetX,
      offsetY,
      contentWidth * scale,
      contentHeight * scale
    );

    // Draw viewport rectangle
    ctx.strokeStyle = '#1976D2';
    ctx.lineWidth = 2;
    ctx.fillStyle = 'rgba(25, 118, 210, 0.1)';
    ctx.fillRect(viewportX, viewportY, viewportWidth, viewportHeight);
    ctx.strokeRect(viewportX, viewportY, viewportWidth, viewportHeight);

  }, [zoom, panX, panY, scale, contentWidth, contentHeight, viewportWidth, viewportHeight, viewportX, viewportY]);

  // Handle minimap click/drag to pan
  const handleMouseDown = useCallback((e: React.MouseEvent<HTMLCanvasElement>) => {
    isDragging.current = true;
    handlePan(e);
  }, []);

  const handleMouseMove = useCallback((e: React.MouseEvent<HTMLCanvasElement>) => {
    if (!isDragging.current) return;
    handlePan(e);
  }, []);

  const handleMouseUp = useCallback(() => {
    isDragging.current = false;
  }, []);

  const handlePan = useCallback((e: React.MouseEvent<HTMLCanvasElement>) => {
    const canvas = canvasRef.current;
    if (!canvas) return;

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

    // Convert minimap coordinates back to canvas pan coordinates
    const offsetX = (MINIMAP_WIDTH - contentWidth * scale) / 2;
    const offsetY = (MINIMAP_HEIGHT - contentHeight * scale) / 2;

    const contentX = (x - offsetX) / scale + contentBounds.x1;
    const contentY = (y - offsetY) / scale + contentBounds.y1;

    // Center viewport on clicked point
    const newPanX = -(contentX - containerWidth / (2 * zoom)) * zoom;
    const newPanY = -(contentY - containerHeight / (2 * zoom)) * zoom;

    dispatch(setPan({ x: newPanX, y: newPanY }));

    if (onViewportChange) {
      onViewportChange(newPanX, newPanY, zoom);
    }
  }, [dispatch, zoom, containerWidth, containerHeight, contentBounds, scale, contentWidth, contentHeight, onViewportChange]);

  const handleZoomIn = useCallback(() => {
    dispatch(zoomIn());
  }, [dispatch]);

  const handleZoomOut = useCallback(() => {
    dispatch(zoomOut());
  }, [dispatch]);

  const handleResetView = useCallback(() => {
    dispatch(resetView());
    if (onFitToView) {
      onFitToView();
    }
  }, [dispatch, onFitToView]);

  if (!showMinimap) {
    return null;
  }

  return (
    <Paper
      elevation={3}
      sx={{
        position: 'absolute',
        bottom: 16,
        right: 16,
        p: 1,
        bgcolor: 'background.paper',
        borderRadius: 1,
      }}
    >
      {/* Minimap canvas */}
      <Box
        sx={{
          width: MINIMAP_WIDTH,
          height: MINIMAP_HEIGHT,
          cursor: 'crosshair',
          borderRadius: 0.5,
          overflow: 'hidden',
        }}
      >
        <canvas
          ref={canvasRef}
          width={MINIMAP_WIDTH}
          height={MINIMAP_HEIGHT}
          onMouseDown={handleMouseDown}
          onMouseMove={handleMouseMove}
          onMouseUp={handleMouseUp}
          onMouseLeave={handleMouseUp}
        />
      </Box>

      {/* Zoom controls */}
      <Box
        sx={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          mt: 0.5,
          px: 0.5,
        }}
      >
        <Tooltip title="Zoom out">
          <IconButton size="small" onClick={handleZoomOut}>
            <ZoomOutIcon fontSize="small" />
          </IconButton>
        </Tooltip>

        <Box
          sx={{
            fontSize: 11,
            color: 'text.secondary',
            fontWeight: 500,
          }}
        >
          {Math.round(zoom * 100)}%
        </Box>

        <Tooltip title="Zoom in">
          <IconButton size="small" onClick={handleZoomIn}>
            <ZoomInIcon fontSize="small" />
          </IconButton>
        </Tooltip>

        <Tooltip title="Reset view">
          <IconButton size="small" onClick={handleResetView}>
            <CenterIcon fontSize="small" />
          </IconButton>
        </Tooltip>

        <Tooltip title="Fit to view">
          <IconButton size="small" onClick={onFitToView}>
            <FullscreenIcon fontSize="small" />
          </IconButton>
        </Tooltip>
      </Box>
    </Paper>
  );
};

export default CanvasMinimap;
