import { useState, useCallback } from 'react';
import type { UseFileUploadReturn } from './types';

const ACCEPTED_EXTENSIONS = ['xlsx', 'docx', 'pptx', 'pdf'];
const MAX_FILE_SIZE = 50 * 1024 * 1024;
/** Batch cap — keeps a drag-and-dropped folder from turning into a runaway queue. */
export const MAX_BATCH_FILES = 10;

// i18n keys — rendered through t() so the message follows the UI locale.
export const ERROR_MESSAGES = {
  INVALID_FORMAT: 'fileUploader.error.invalidFormat',
  FILE_TOO_LARGE: 'fileUploader.error.tooLarge',
  TOO_MANY: 'fileUploader.error.tooMany',
} as const;

export function useFileUpload(): UseFileUploadReturn {
  const [files, setFiles] = useState<File[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [isDragOver, setIsDragOver] = useState(false);

  const validateFile = useCallback((file: File): string | null => {
    const ext = file.name.split('.').pop()?.toLowerCase();
    if (!ext || !ACCEPTED_EXTENSIONS.includes(ext)) {
      return ERROR_MESSAGES.INVALID_FORMAT;
    }
    if (file.size > MAX_FILE_SIZE) {
      return ERROR_MESSAGES.FILE_TOO_LARGE;
    }
    return null;
  }, []);

  /** Append files, validating each; keeps the first invalid-file message. */
  const addFiles = useCallback((incoming: Iterable<File>) => {
    setError(null);
    setFiles((current) => {
      const next = [...current];
      let firstError: string | null = null;
      for (const file of incoming) {
        const validationError = validateFile(file);
        if (validationError) {
          firstError ??= validationError;
          continue;
        }
        const duplicate = next.some(
          (f) => f.name === file.name && f.size === file.size && f.lastModified === file.lastModified
        );
        if (!duplicate) next.push(file);
      }
      if (next.length > MAX_BATCH_FILES) {
        firstError ??= ERROR_MESSAGES.TOO_MANY;
        next.length = MAX_BATCH_FILES;
      }
      if (firstError) setError(firstError);
      return next;
    });
  }, [validateFile]);

  const removeAt = useCallback((index: number) => {
    setFiles((current) => current.filter((_, i) => i !== index));
  }, []);

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragOver(false);
    const dropped = Array.from(e.dataTransfer.files ?? []);
    if (dropped.length > 0) addFiles(dropped);
  }, [addFiles]);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragOver(true);
  }, []);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragOver(false);
  }, []);

  const handleFileSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const selected = Array.from(e.target.files ?? []);
    if (selected.length > 0) addFiles(selected);
    // allow re-selecting the same file after removal
    e.target.value = '';
  }, [addFiles]);

  const removeFile = useCallback(() => {
    setFiles([]);
    setError(null);
    setIsDragOver(false);
  }, []);

  // Single-file compatibility: the first file drives the existing one-file flow.
  const file = files[0] ?? null;

  return {
    file,
    files,
    error,
    isDragOver,
    handleDrop,
    handleDragOver,
    handleDragLeave,
    handleFileSelect,
    addFiles,
    removeAt,
    removeFile,
  };
}
