/**
 * @ai-summary Hook for submitting and polling manual maintenance extraction jobs
 * @ai-context Submits PDF to OCR endpoint, polls for status, returns extraction results
 */

import { useState, useCallback } from 'react';
import { useQuery, useMutation } from '@tanstack/react-query';
import { apiClient } from '../../../core/api/client';

// Types matching backend ManualJobResponse / ManualExtractionResult
export interface ManualVehicleInfo {
  make: string | null;
  model: string | null;
  year: number | null;
}

export interface MaintenanceScheduleItem {
  service: string;
  intervalMiles: number | null;
  intervalMonths: number | null;
  details: string | null;
  confidence: number;
  subtypes: string[];
}

export interface ManualExtractionResult {
  success: boolean;
  vehicleInfo: ManualVehicleInfo;
  maintenanceSchedules: MaintenanceScheduleItem[];
  rawTables: unknown[];
  processingTimeMs: number;
  totalPages: number;
  pagesProcessed: number;
  error: string | null;
}

export type JobStatus = 'pending' | 'processing' | 'completed' | 'failed';

export interface ManualJobResponse {
  jobId: string;
  status: JobStatus;
  progress?: number;
  estimatedSeconds?: number;
  result?: ManualExtractionResult;
  error?: string;
}

async function submitManualExtraction(file: File, vehicleId: string): Promise<ManualJobResponse> {
  const form = new FormData();
  form.append('file', file);
  form.append('vehicle_id', vehicleId);
  const res = await apiClient.post<ManualJobResponse>('/ocr/extract/manual', form, {
    headers: { 'Content-Type': 'multipart/form-data' },
    timeout: 120000,
  });
  return res.data;
}

async function getJobStatus(jobId: string): Promise<ManualJobResponse> {
  const res = await apiClient.get<ManualJobResponse>(`/ocr/jobs/${jobId}`);
  return res.data;
}

export function useManualExtraction() {
  const [jobId, setJobId] = useState<string | null>(null);

  const submitMutation = useMutation({
    mutationFn: ({ file, vehicleId }: { file: File; vehicleId: string }) =>
      submitManualExtraction(file, vehicleId),
    onSuccess: (data) => {
      setJobId(data.jobId);
    },
  });

  const pollQuery = useQuery<ManualJobResponse>({
    queryKey: ['manualExtractionJob', jobId],
    queryFn: () => getJobStatus(jobId!),
    enabled: !!jobId,
    refetchInterval: (query) => {
      const data = query.state.data;
      if (data?.status === 'completed' || data?.status === 'failed') {
        return false;
      }
      return 3000;
    },
    refetchIntervalInBackground: false,
    retry: 2,
  });

  const submit = useCallback(
    (file: File, vehicleId: string) => submitMutation.mutateAsync({ file, vehicleId }),
    [submitMutation]
  );

  const reset = useCallback(() => {
    setJobId(null);
    submitMutation.reset();
  }, [submitMutation]);

  const jobData = pollQuery.data;
  const hasPollError = !!pollQuery.error;
  const status: JobStatus | 'idle' = !jobId
    ? 'idle'
    : hasPollError
    ? 'failed'
    : jobData?.status ?? 'pending';
  const progress = jobData?.progress ?? 0;
  const result = jobData?.result ?? null;

  let error: string | null = null;
  if (jobData?.error) {
    error = jobData.error;
  } else if (pollQuery.error) {
    const err = pollQuery.error as any;
    if (err.response?.status === 410) {
      error = 'Job expired. Please resubmit the document.';
    } else {
      error = String((err as Error).message || err);
    }
  } else if (submitMutation.error) {
    error = String((submitMutation.error as Error).message || submitMutation.error);
  }

  return {
    submit,
    isSubmitting: submitMutation.isPending,
    jobId,
    status,
    progress,
    result,
    error,
    reset,
  };
}
