import { Box } from '@/ui/Box';
import { Icon } from '@/ui/Icon';
import { IconButton } from '@/ui/IconButton';
import { ListItem, ListItemActions, ListItemInfo } from '@/ui/ListItem';
import { Surface } from '@/ui/Surface';
import { Text } from '@/ui/Text';
import { AlertCircle, CheckCircle2, Upload, X } from 'lucide-react';
import React, { useRef, useState } from 'react';

export interface UploadDropzoneProps {
  onFilesSelected: (files: File[]) => void;
  accept?: string;
  multiple?: boolean;
  maxSize?: number; // in bytes
  isLoading?: boolean;
  error?: string;
}

export function UploadDropzone({
  onFilesSelected,
  accept,
  multiple = false,
  maxSize,
  isLoading,
  error,
}: UploadDropzoneProps) {
  const [isDragging, setIsDragging] = useState(false);
  const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(true);
  };

  const handleDragLeave = () => {
    setIsDragging(false);
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
    const files = Array.from(e.dataTransfer.files);
    validateAndSelectFiles(files);
  };

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      const files = Array.from(e.target.files);
      validateAndSelectFiles(files);
    }
  };

  const validateAndSelectFiles = (files: File[]) => {
    let filteredFiles = files;
    
    if (accept) {
      const acceptedTypes = accept.split(',').map(t => t.trim());
      filteredFiles = filteredFiles.filter(file => {
        return acceptedTypes.some(type => {
          if (type.startsWith('.')) {
            return file.name.endsWith(type);
          }
          if (type.endsWith('/*')) {
            return file.type.startsWith(type.replace('/*', ''));
          }
          return file.type === type;
        });
      });
    }

    if (maxSize) {
      filteredFiles = filteredFiles.filter(file => file.size <= maxSize);
    }

    if (!multiple) {
      filteredFiles = filteredFiles.slice(0, 1);
    }

    setSelectedFiles(filteredFiles);
    onFilesSelected(filteredFiles);
  };

  const removeFile = (index: number) => {
    const newFiles = [...selectedFiles];
    newFiles.splice(index, 1);
    setSelectedFiles(newFiles);
    onFilesSelected(newFiles);
  };

  return (
    <Box 
      fullWidth
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
    >
      <Surface
        variant="muted"
        rounded="xl"
        padding={8}
        onClick={() => fileInputRef.current?.click()}
        style={{ 
          border: `2px dashed ${isDragging ? 'var(--ui-color-intent-primary)' : (error ? 'var(--ui-color-intent-critical)' : 'var(--ui-color-border-default)')}`,
          backgroundColor: isDragging ? 'rgba(25, 140, 255, 0.05)' : 'var(--ui-color-bg-surface-muted)',
          textAlign: 'center',
          cursor: 'pointer'
        }}
      >
        <Box
          as="input"
          type="file"
          ref={fileInputRef}
          onChange={handleFileSelect}
          accept={accept}
          multiple={multiple}
          style={{ display: 'none' }}
        />
        
        <Box display="flex" flexDirection="col" alignItems="center" gap={4}>
          <Icon 
            icon={isLoading ? Upload : (selectedFiles.length > 0 ? CheckCircle2 : Upload)} 
            size={10} 
            intent={isDragging ? 'primary' : (error ? 'critical' : 'low')}
            animate={isLoading ? 'pulse' : 'none'}
          />
          
          <Box>
            <Text weight="bold" variant="high" size="lg" block marginBottom={1}>
              {isDragging ? 'Drop files here' : 'Click or drag to upload'}
            </Text>
            
            <Text size="sm" variant="low" block>
              {accept ? `Accepted formats: ${accept}` : 'All file types accepted'}
              {maxSize && ` (Max ${Math.round(maxSize / 1024 / 1024)}MB)`}
            </Text>
          </Box>

          {error && (
            <Box display="flex" alignItems="center" gap={2} marginTop={2}>
              <Icon icon={AlertCircle} size={4} intent="warning" />
              <Text size="sm" variant="warning" weight="medium">{error}</Text>
            </Box>
          )}
        </Box>
      </Surface>

      {selectedFiles.length > 0 && (
        <Box marginTop={4} display="flex" flexDirection="col" gap={2}>
          {selectedFiles.map((file, index) => (
            <ListItem key={`${file.name}-${index}`}>
              <ListItemInfo
                title={file.name}
                description={`${Math.round(file.size / 1024)} KB`}
              />
              <ListItemActions>
                <IconButton 
                  icon={X} 
                  size="sm" 
                  variant="ghost" 
                  onClick={(e) => {
                    e.stopPropagation();
                    removeFile(index);
                  }}
                  title="Remove"
                />
              </ListItemActions>
            </ListItem>
          ))}
        </Box>
      )}
    </Box>
  );
}
