import { useState, useEffect } from 'react';
import { uploadDocument } from '@/services/documentApi';
import { getPublicConfigurations, AdminConfiguration } from '@/services/adminApi';
import { toast } from 'sonner';
import { handleSecurityError } from '@/utils/securityToast';

/**
 * Custom Hook: useDocumentUpload
 * 
 * Purpose: Manages document upload functionality with loading states
 * 
 * Responsibilities:
 * - Handles file input change events
 * - Validates file selection
 * - Uploads document to backend
 * - Triggers refresh after successful upload
 * - Manages upload loading state
 * - Handles errors with user-friendly messages
 * 
 * @param apiRequest - Current request object (contains requestId for upload)
 * @param refreshDetails - Function to refresh request data after upload
 * @returns Object with upload handler, trigger function, and loading state
 */
export function useDocumentUpload(
  apiRequest: any,
  refreshDetails: () => Promise<void>
) {
  // State: Indicates if document is currently being uploaded
  const [uploadingDocument, setUploadingDocument] = useState(false);

  // State: Stores document for preview modal
  const [previewDocument, setPreviewDocument] = useState<{
    fileName: string;
    fileType: string;
    documentId: string;
    fileSize?: number;
  } | null>(null);

  // Document policy state
  const [documentPolicy, setDocumentPolicy] = useState<{
    maxFileSizeMB: number;
    allowedFileTypes: string[];
  }>({
    maxFileSizeMB: 10,
    allowedFileTypes: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'jpg', 'jpeg', 'png', 'gif']
  });

  // Document validation error state
  const [documentError, setDocumentError] = useState<{
    show: boolean;
    errors: Array<{ fileName: string; reason: string }>;
  }>({
    show: false,
    errors: []
  });

  // Fetch document policy on mount
  useEffect(() => {
    const loadDocumentPolicy = async () => {
      try {
        const configs = await getPublicConfigurations('DOCUMENT_POLICY');
        const configMap: Record<string, string> = {};
        configs.forEach((c: AdminConfiguration) => {
          configMap[c.configKey] = c.configValue;
        });

        const maxFileSizeMB = parseInt(configMap['MAX_FILE_SIZE_MB'] || '10');
        const allowedFileTypesStr = configMap['ALLOWED_FILE_TYPES'] || 'pdf,doc,docx,xls,xlsx,ppt,pptx,jpg,jpeg,png,gif';
        const allowedFileTypes = allowedFileTypesStr.split(',').map(ext => ext.trim().toLowerCase());

        setDocumentPolicy({
          maxFileSizeMB,
          allowedFileTypes
        });
      } catch (error) {
        console.error('Failed to load document policy:', error);
        // Use defaults if loading fails
      }
    };

    loadDocumentPolicy();
  }, []);

  /**
   * Function: validateFile
   * 
   * Purpose: Validate file against document policy
   * 
   * @param file - File to validate
   * @returns Validation result with reason if invalid
   */
  const validateFile = (file: File): { valid: boolean; reason?: string } => {
    // Check file size
    const maxSizeBytes = documentPolicy.maxFileSizeMB * 1024 * 1024;
    if (file.size > maxSizeBytes) {
      return {
        valid: false,
        reason: `File size exceeds the maximum allowed size of ${documentPolicy.maxFileSizeMB}MB. Current size: ${(file.size / (1024 * 1024)).toFixed(2)}MB`
      };
    }

    // Check file extension
    const fileName = file.name.toLowerCase();
    const fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1);

    if (!documentPolicy.allowedFileTypes.includes(fileExtension)) {
      return {
        valid: false,
        reason: `File type "${fileExtension}" is not allowed. Allowed types: ${documentPolicy.allowedFileTypes.join(', ')}`
      };
    }

    return { valid: true };
  };

  /**
   * Function: handleDocumentUpload
   * 
   * Purpose: Process file upload when user selects a file
   * 
   * Process:
   * 1. Validate file selection
   * 2. Validate against document policy
   * 3. Get request UUID (required for backend API)
   * 4. Upload file to backend
   * 5. Refresh request details to show new document
   * 6. Clear file input for next upload
   * 7. Show success/error messages
   * 
   * @param event - File input change event
   */
  const handleDocumentUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const files = event.target.files;

    // Validate: Check if file is selected
    if (!files || files.length === 0) return;

    const fileArray = Array.from(files);

    // Validate all files against document policy
    const validationErrors: Array<{ fileName: string; reason: string }> = [];
    const validFiles: File[] = [];

    fileArray.forEach(file => {
      const validation = validateFile(file);
      if (!validation.valid) {
        validationErrors.push({
          fileName: file.name,
          reason: validation.reason || 'Unknown validation error'
        });
      } else {
        validFiles.push(file);
      }
    });

    // If there are validation errors, show modal
    if (validationErrors.length > 0) {
      setDocumentError({
        show: true,
        errors: validationErrors
      });
    }

    // If no valid files, stop here
    if (validFiles.length === 0) {
      if (event.target) {
        event.target.value = '';
      }
      return;
    }

    setUploadingDocument(true);

    try {
      // Upload only the first valid file (backend currently supports single file)
      const file = validFiles[0];

      // Validate: Ensure request ID is available
      // Note: Backend requires UUID, not request number
      const requestId = apiRequest?.requestId;
      if (!requestId) {
        toast.error('Request ID not found');
        return;
      }

      // API Call: Upload document to backend
      // Document type is 'SUPPORTING' (as opposed to 'REQUIRED')
      if (file) {
        await uploadDocument(file, requestId, 'SUPPORTING');
      }

      // Refresh: Reload request details to show newly uploaded document
      // This also updates the activity timeline
      await refreshDetails();

      // Success feedback
      if (validFiles.length < fileArray.length) {
        toast.warning(`${validFiles.length} of ${fileArray.length} file(s) were uploaded. ${validationErrors.length} file(s) were rejected.`);
      } else {
        toast.success('Document uploaded successfully');
      }
    } catch (error: any) {
      console.error('[useDocumentUpload] Upload error:', error);

      // Show security-specific red toast for scan errors, or generic error toast
      if (!handleSecurityError(error)) {
        toast.error(error?.response?.data?.message || 'Failed to upload document');
      }
    } finally {
      setUploadingDocument(false);

      // Cleanup: Clear the file input to allow re-uploading same file
      if (event.target) {
        event.target.value = '';
      }
    }
  };

  /**
   * Function: triggerFileInput
   * 
   * Purpose: Programmatically open file picker dialog
   * 
   * Process:
   * 1. Create temporary file input element
   * 2. Configure accepted file types based on document policy
   * 3. Attach upload handler
   * 4. Trigger click to open file picker
   */
  const triggerFileInput = () => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = documentPolicy.allowedFileTypes.map(ext => `.${ext}`).join(',');
    input.onchange = handleDocumentUpload as any;
    input.click();
  };

  return {
    uploadingDocument,
    handleDocumentUpload,
    triggerFileInput,
    previewDocument,
    setPreviewDocument,
    documentPolicy,
    documentError,
    setDocumentError
  };
}

