// =============================================================================
// useConverter Hook
// React hook wrapping the conversion broker for component use
// =============================================================================

import { useEffect, useState, useCallback, useRef } from 'react';
import type { QueueItem, SupportedFormat, ConversionOptions } from '../core/types';
import { conversionBroker, ConversionBroker } from '../services/conversion-broker';
import { detectFormat, getCompatibleOutputFormats } from '../core/format-utils';

export interface UseConverterReturn {
  /** Current queue items */
  queue: QueueItem[];
  /** Is the broker currently processing? */
  isProcessing: boolean;
  /** Add a single file to the queue */
  addFile: (file: File, targetFormat: SupportedFormat, options?: ConversionOptions) => QueueItem | null;
  /** Add multiple files to the queue */
  addFiles: (files: File[], targetFormat: SupportedFormat, options?: ConversionOptions) => QueueItem[];
  /** Remove an item from the queue */
  removeItem: (id: string) => void;
  /** Process all pending items */
  processAll: () => Promise<void>;
  /** Clear completed and errored items */
  clearCompleted: () => void;
  /** Clear entire queue */
  clearQueue: () => void;
  /** Download a converted file */
  downloadItem: (item: QueueItem) => void;
  /** Download all completed files */
  downloadAll: () => void;
  /** Get compatible output formats for a file */
  getOutputFormats: (file: File) => SupportedFormat[];
}

export function useConverter(broker: ConversionBroker = conversionBroker): UseConverterReturn {
  const [queue, setQueue] = useState<QueueItem[]>([]);
  const [isProcessing, setIsProcessing] = useState(false);
  const processingRef = useRef(false);

  // Subscribe to broker updates
  useEffect(() => {
    const unsubscribe = broker.subscribe((newQueue) => {
      setQueue(newQueue);
      // Track processing state
      const hasProcessing = newQueue.some(item => item.status === 'processing');
      const hasPending = newQueue.some(item => item.status === 'pending');
      setIsProcessing(hasProcessing || (processingRef.current && hasPending));
    });

    return unsubscribe;
  }, [broker]);

  const addFile = useCallback(
    (file: File, targetFormat: SupportedFormat, options?: ConversionOptions) => {
      return broker.addToQueue(file, targetFormat, options);
    },
    [broker]
  );

  const addFiles = useCallback(
    (files: File[], targetFormat: SupportedFormat, options?: ConversionOptions) => {
      return broker.addFilesToQueue(files, targetFormat, options);
    },
    [broker]
  );

  const removeItem = useCallback(
    (id: string) => {
      broker.removeFromQueue(id);
    },
    [broker]
  );

  const processAll = useCallback(async () => {
    processingRef.current = true;
    setIsProcessing(true);
    try {
      await broker.processQueue();
    } finally {
      processingRef.current = false;
      setIsProcessing(false);
    }
  }, [broker]);

  const clearCompleted = useCallback(() => {
    broker.clearCompleted();
  }, [broker]);

  const clearQueue = useCallback(() => {
    broker.clearQueue();
  }, [broker]);

  const downloadItem = useCallback(
    (item: QueueItem) => {
      broker.downloadItem(item);
    },
    [broker]
  );

  const downloadAll = useCallback(() => {
    queue
      .filter(item => item.status === 'complete')
      .forEach(item => broker.downloadItem(item));
  }, [broker, queue]);

  const getOutputFormats = useCallback((file: File): SupportedFormat[] => {
    const inputFormat = detectFormat(file);
    if (!inputFormat) return [];
    return getCompatibleOutputFormats(inputFormat);
  }, []);

  return {
    queue,
    isProcessing,
    addFile,
    addFiles,
    removeItem,
    processAll,
    clearCompleted,
    clearQueue,
    downloadItem,
    downloadAll,
    getOutputFormats,
  };
}
