import { useState, useCallback, useRef, type ReactNode, type DragEvent } from 'react';
import { Typography } from 'antd';
import { CloudUploadOutlined } from '@ant-design/icons';

const { Text, Title } = Typography;

interface FullPageDropZoneProps {
  children: ReactNode;
  onDrop: (files: File[]) => void;
  accept?: string[];
  disabled?: boolean;
  maxFileSize?: number;
}

const DEFAULT_ACCEPT = ['application/pdf', 'image/png', 'image/jpeg', 'image/jpg'];
const DEFAULT_MAX_SIZE = 10 * 1024 * 1024; // 10MB

/**
 * Full-page drop zone wrapper component.
 * Shows an overlay when dragging files over the page.
 */
export function FullPageDropZone({
  children,
  onDrop,
  accept = DEFAULT_ACCEPT,
  disabled = false,
  maxFileSize = DEFAULT_MAX_SIZE,
}: FullPageDropZoneProps) {
  const [isDragging, setIsDragging] = useState(false);
  const dragCounter = useRef(0);

  const isValidFile = useCallback(
    (file: File): boolean => {
      // Check file type
      const isValidType = accept.some((type) => {
        if (type.includes('*')) {
          // Handle wildcards like 'image/*'
          const baseType = type.split('/')[0];
          return file.type.startsWith(baseType + '/');
        }
        return file.type === type;
      });

      if (!isValidType) {
        return false;
      }

      // Check file size
      if (file.size > maxFileSize) {
        return false;
      }

      return true;
    },
    [accept, maxFileSize]
  );

  const handleDragEnter = useCallback(
    (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();

      if (disabled) return;

      dragCounter.current++;
      if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
        setIsDragging(true);
      }
    },
    [disabled]
  );

  const handleDragLeave = useCallback(
    (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();

      if (disabled) return;

      dragCounter.current--;
      if (dragCounter.current === 0) {
        setIsDragging(false);
      }
    },
    [disabled]
  );

  const handleDragOver = useCallback(
    (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();

      if (disabled) return;

      // Set the drop effect
      if (e.dataTransfer) {
        e.dataTransfer.dropEffect = 'copy';
      }
    },
    [disabled]
  );

  const handleDrop = useCallback(
    (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();

      setIsDragging(false);
      dragCounter.current = 0;

      if (disabled) return;

      const files = Array.from(e.dataTransfer.files);
      const validFiles = files.filter(isValidFile);

      if (validFiles.length > 0) {
        onDrop(validFiles);
      }
    },
    [disabled, isValidFile, onDrop]
  );

  return (
    <div
      style={{ position: 'relative', minHeight: '100%' }}
      onDragEnter={handleDragEnter}
      onDragLeave={handleDragLeave}
      onDragOver={handleDragOver}
      onDrop={handleDrop}
    >
      {children}

      {/* Overlay when dragging */}
      {isDragging && (
        <div
          style={{
            position: 'fixed',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            backgroundColor: 'rgba(24, 144, 255, 0.1)',
            border: '3px dashed #1890ff',
            borderRadius: 8,
            zIndex: 1000,
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'center',
            pointerEvents: 'none',
          }}
        >
          <CloudUploadOutlined
            style={{
              fontSize: 64,
              color: '#1890ff',
              marginBottom: 16,
            }}
          />
          <Title level={3} style={{ color: '#1890ff', margin: 0 }}>
            Slip dokumentet her
          </Title>
          <Text type="secondary" style={{ marginTop: 8 }}>
            PDF, PNG eller JPG (maks 10MB)
          </Text>
        </div>
      )}
    </div>
  );
}

export default FullPageDropZone;
