/**
 * @ai-summary Post-capture crop tool with draggable handles
 * @ai-context Allows user to adjust crop area with touch/mouse, confirm or retake
 */

import React, { useCallback, useState, useRef, useEffect } from 'react';
import { Box, IconButton, Button, Typography, CircularProgress, useMediaQuery } from '@mui/material';
import CheckIcon from '@mui/icons-material/Check';
import RefreshIcon from '@mui/icons-material/Refresh';
import ReplayIcon from '@mui/icons-material/Replay';
import SkipNextIcon from '@mui/icons-material/SkipNext';
import type { CropToolProps } from './types';
import { useImageCrop, type CropHandle } from './useImageCrop';

export const CropTool: React.FC<CropToolProps> = ({
  imageSrc,
  lockAspectRatio = false,
  initialCrop,
  aspectRatio,
  onConfirm,
  onReset,
  onRetake,
  onSkip,
}) => {
  const [isProcessing, setIsProcessing] = useState(false);
  const imageAreaRef = useRef<HTMLDivElement>(null);
  const [imageMaxHeight, setImageMaxHeight] = useState(0);

  // Responsive handle sizing: 44px standard, 32px on compact viewports
  const isCompactViewport = useMediaQuery('(max-height: 400px)');
  const handleConfig = { size: isCompactViewport ? 32 : 44, visual: isCompactViewport ? 12 : 16 };

  const { cropArea, cropDrawn, isDragging, resetCrop, executeCrop, handleDragStart, handleDrawStart } =
    useImageCrop({
      aspectRatio: lockAspectRatio ? aspectRatio : undefined,
      initialCrop,
    });

  const showCropArea = cropDrawn || (isDragging && cropArea.width > 1 && cropArea.height > 1);

  // Measure available height for the image so the crop container
  // matches the rendered image exactly (fixes mobile crop offset)
  useEffect(() => {
    const updateMaxHeight = () => {
      if (imageAreaRef.current) {
        const rect = imageAreaRef.current.getBoundingClientRect();
        setImageMaxHeight(rect.height - 32); // subtract p:2 padding (16px * 2)
      }
    };
    updateMaxHeight();
    window.addEventListener('resize', updateMaxHeight);
    return () => window.removeEventListener('resize', updateMaxHeight);
  }, []);

  const handleConfirm = useCallback(async () => {
    setIsProcessing(true);
    try {
      const croppedBlob = await executeCrop(imageSrc);
      onConfirm(croppedBlob);
    } catch (error) {
      console.error('Failed to crop image:', error);
      // On error, skip cropping and use original
      onSkip();
    } finally {
      setIsProcessing(false);
    }
  }, [executeCrop, imageSrc, onConfirm, onSkip]);

  const handleReset = useCallback(() => {
    resetCrop();
    onReset();
  }, [resetCrop, onReset]);

  return (
    <Box
      sx={{
        position: 'relative',
        width: '100%',
        height: '100%',
        backgroundColor: 'black',
        display: 'flex',
        flexDirection: 'column',
        overflow: 'hidden',
      }}
    >
      {/* Image with crop overlay */}
      <Box
        ref={imageAreaRef}
        sx={{
          flex: 1,
          position: 'relative',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          overflow: 'hidden',
          p: 2,
        }}
      >
        <Box
          data-crop-container
          sx={{
            position: 'relative',
            userSelect: 'none',
            touchAction: isDragging ? 'none' : 'auto',
          }}
        >
          {/* Source image */}
          <img
            src={imageSrc}
            alt="Captured"
            style={{
              maxWidth: '100%',
              maxHeight: imageMaxHeight > 0 ? `${imageMaxHeight}px` : '70vh',
              display: 'block',
            }}
            draggable={false}
          />

          {/* Draw surface for free-form rectangle drawing */}
          {!cropDrawn && (
            <Box
              onMouseDown={handleDrawStart}
              onTouchStart={handleDrawStart}
              sx={{
                position: 'absolute',
                inset: 0,
                cursor: 'crosshair',
                zIndex: 5,
                touchAction: 'none',
              }}
            />
          )}

          {/* Dark overlay outside crop area */}
          {showCropArea && (
            <Box
              sx={{
                position: 'absolute',
                inset: 0,
                pointerEvents: 'none',
              }}
            >
              {/* Top overlay */}
              <Box
                sx={{
                  position: 'absolute',
                  top: 0,
                  left: 0,
                  right: 0,
                  height: `${cropArea.y}%`,
                  backgroundColor: 'rgba(0, 0, 0, 0.6)',
                }}
              />
              {/* Bottom overlay */}
              <Box
                sx={{
                  position: 'absolute',
                  bottom: 0,
                  left: 0,
                  right: 0,
                  height: `${100 - cropArea.y - cropArea.height}%`,
                  backgroundColor: 'rgba(0, 0, 0, 0.6)',
                }}
              />
              {/* Left overlay */}
              <Box
                sx={{
                  position: 'absolute',
                  top: `${cropArea.y}%`,
                  left: 0,
                  width: `${cropArea.x}%`,
                  height: `${cropArea.height}%`,
                  backgroundColor: 'rgba(0, 0, 0, 0.6)',
                }}
              />
              {/* Right overlay */}
              <Box
                sx={{
                  position: 'absolute',
                  top: `${cropArea.y}%`,
                  right: 0,
                  width: `${100 - cropArea.x - cropArea.width}%`,
                  height: `${cropArea.height}%`,
                  backgroundColor: 'rgba(0, 0, 0, 0.6)',
                }}
              />
            </Box>
          )}

          {/* Crop area border and handles */}
          {showCropArea && (
            <Box
              sx={{
                position: 'absolute',
                top: `${cropArea.y}%`,
                left: `${cropArea.x}%`,
                width: `${cropArea.width}%`,
                height: `${cropArea.height}%`,
                border: '2px solid white',
                boxSizing: 'border-box',
              }}
            >
              {/* Handles only appear after drawing is complete */}
              {cropDrawn && (
                <>
                  {/* Move handle (center area) */}
                  <CropHandleArea
                    handle="move"
                    onDragStart={handleDragStart}
                    sx={{
                      position: 'absolute',
                      inset: handleConfig.size / 2,
                      cursor: 'move',
                    }}
                  />

                  {/* Corner handles */}
                  <CropHandle handle="nw" onDragStart={handleDragStart} position="top-left" config={handleConfig} />
                  <CropHandle handle="ne" onDragStart={handleDragStart} position="top-right" config={handleConfig} />
                  <CropHandle handle="sw" onDragStart={handleDragStart} position="bottom-left" config={handleConfig} />
                  <CropHandle handle="se" onDragStart={handleDragStart} position="bottom-right" config={handleConfig} />

                  {/* Edge handles */}
                  <CropHandle handle="n" onDragStart={handleDragStart} position="top" config={handleConfig} />
                  <CropHandle handle="s" onDragStart={handleDragStart} position="bottom" config={handleConfig} />
                  <CropHandle handle="w" onDragStart={handleDragStart} position="left" config={handleConfig} />
                  <CropHandle handle="e" onDragStart={handleDragStart} position="right" config={handleConfig} />
                </>
              )}

              {/* Grid lines for alignment */}
              <Box
                sx={{
                  position: 'absolute',
                  inset: 0,
                  display: 'grid',
                  gridTemplateColumns: '1fr 1fr 1fr',
                  gridTemplateRows: '1fr 1fr 1fr',
                  pointerEvents: 'none',
                  opacity: isDragging ? 1 : 0.5,
                  transition: 'opacity 0.2s',
                }}
              >
                {Array.from({ length: 9 }).map((_, i) => (
                  <Box
                    key={i}
                    sx={{
                      borderRight: i % 3 !== 2 ? '1px solid rgba(255,255,255,0.3)' : 'none',
                      borderBottom: i < 6 ? '1px solid rgba(255,255,255,0.3)' : 'none',
                    }}
                  />
                ))}
              </Box>
            </Box>
          )}
        </Box>
      </Box>

      {/* Instructions */}
      <Box sx={{ px: 2, py: 1, textAlign: 'center' }}>
        <Typography variant="body2" sx={{ color: 'rgba(255, 255, 255, 0.7)' }}>
          {cropDrawn ? 'Drag handles to adjust crop area' : 'Tap and drag to select crop area'}
        </Typography>
      </Box>

      {/* Action buttons */}
      <Box
        sx={{
          display: 'flex',
          justifyContent: 'space-around',
          alignItems: 'center',
          p: 2,
          gap: 2,
          background: 'linear-gradient(to top, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.5) 100%)',
        }}
      >
        <Button
          onClick={onRetake}
          startIcon={<ReplayIcon />}
          sx={{ color: 'white' }}
          disabled={isProcessing}
        >
          Retake
        </Button>

        <Button
          onClick={handleReset}
          startIcon={<RefreshIcon />}
          sx={{ color: 'white' }}
          disabled={isProcessing || !cropDrawn}
        >
          Reset
        </Button>

        <Button
          onClick={onSkip}
          startIcon={<SkipNextIcon />}
          sx={{ color: 'white' }}
          disabled={isProcessing}
        >
          Skip
        </Button>

        <IconButton
          onClick={handleConfirm}
          disabled={isProcessing || !cropDrawn}
          aria-label="Confirm crop"
          sx={{
            width: 56,
            height: 56,
            backgroundColor: 'primary.main',
            color: 'white',
            '&:hover': {
              backgroundColor: 'primary.dark',
            },
            '&:disabled': {
              backgroundColor: 'action.disabled',
            },
          }}
        >
          {isProcessing ? (
            <CircularProgress size={24} color="inherit" />
          ) : (
            <CheckIcon />
          )}
        </IconButton>
      </Box>
    </Box>
  );
};

interface CropHandleProps {
  handle: CropHandle;
  onDragStart: (handle: CropHandle, event: React.MouseEvent | React.TouchEvent) => void;
  config: { size: number; visual: number };
  position:
    | 'top-left'
    | 'top-right'
    | 'bottom-left'
    | 'bottom-right'
    | 'top'
    | 'bottom'
    | 'left'
    | 'right';
}

const CropHandle: React.FC<CropHandleProps> = ({ handle, onDragStart, position, config }) => {
  const handleSize = config.size;
  const handleVisualSize = config.visual;

  const positionStyles: Record<string, React.CSSProperties> = {
    'top-left': {
      top: -handleSize / 2,
      left: -handleSize / 2,
      cursor: 'nwse-resize',
    },
    'top-right': {
      top: -handleSize / 2,
      right: -handleSize / 2,
      cursor: 'nesw-resize',
    },
    'bottom-left': {
      bottom: -handleSize / 2,
      left: -handleSize / 2,
      cursor: 'nesw-resize',
    },
    'bottom-right': {
      bottom: -handleSize / 2,
      right: -handleSize / 2,
      cursor: 'nwse-resize',
    },
    top: {
      top: -handleSize / 2,
      left: '50%',
      transform: 'translateX(-50%)',
      cursor: 'ns-resize',
    },
    bottom: {
      bottom: -handleSize / 2,
      left: '50%',
      transform: 'translateX(-50%)',
      cursor: 'ns-resize',
    },
    left: {
      top: '50%',
      left: -handleSize / 2,
      transform: 'translateY(-50%)',
      cursor: 'ew-resize',
    },
    right: {
      top: '50%',
      right: -handleSize / 2,
      transform: 'translateY(-50%)',
      cursor: 'ew-resize',
    },
  };

  const isCorner = position.includes('-');

  return (
    <Box
      onMouseDown={(e) => onDragStart(handle, e)}
      onTouchStart={(e) => onDragStart(handle, e)}
      sx={{
        position: 'absolute',
        width: handleSize,
        height: handleSize,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        zIndex: 10,
        ...positionStyles[position],
      }}
    >
      <Box
        sx={{
          // Edge handles: 70% of touch target for long dimension, 75% of visual for short dimension
          width: isCorner ? handleVisualSize : position === 'top' || position === 'bottom' ? Math.round(handleSize * 0.7) : Math.round(handleVisualSize * 0.75),
          height: isCorner ? handleVisualSize : position === 'left' || position === 'right' ? Math.round(handleSize * 0.7) : Math.round(handleVisualSize * 0.75),
          backgroundColor: 'white',
          borderRadius: isCorner ? '50%' : 1,
          boxShadow: '0 2px 4px rgba(0,0,0,0.3)',
        }}
      />
    </Box>
  );
};

interface CropHandleAreaProps {
  handle: CropHandle;
  onDragStart: (handle: CropHandle, event: React.MouseEvent | React.TouchEvent) => void;
  sx?: React.CSSProperties & { [key: string]: unknown };
}

const CropHandleArea: React.FC<CropHandleAreaProps> = ({ handle, onDragStart, sx }) => {
  return (
    <Box
      onMouseDown={(e) => onDragStart(handle, e)}
      onTouchStart={(e) => onDragStart(handle, e)}
      sx={sx}
    />
  );
};

export default CropTool;
