import { useQuery, useMutation, useQueryClient, useQueries } from '@tanstack/react-query';
import { apiClient } from '../lib/api';
import type {
  Job,
  JobCreateRequest,
  VttUpdateRequest,
  BulkDeleteRequest,
  BulkApproveRequest,
  BulkReturnToQCRequest,
  TTSPreferences,
  AccessibleVideoMethod
} from '../types/api';

// Query hooks
export function useJobs(filters?: { status?: string; mine?: boolean; page?: number; size?: number }, options?: { enabled?: boolean }) {
  return useQuery({
    queryKey: ['jobs', filters],
    queryFn: () => apiClient.getJobs(filters),
    enabled: options?.enabled ?? true,
    staleTime: 0, // Consider data stale immediately
    refetchOnMount: 'always', // Always fetch fresh data when component mounts
  });
}

export function useJob(jobId: string) {
  return useQuery({
    queryKey: ['jobs', jobId],
    queryFn: () => apiClient.getJob(jobId),
    enabled: !!jobId,
    staleTime: 30000, // 30 seconds
    refetchOnWindowFocus: false,
    refetchInterval: (query) => {
      const status = query.state.data?.status;
      const processingStatuses = new Set([
        'created', 'ingesting', 'ai_processing', 'translating',
        'tts_generating', 'rendering_video', 'rendering_qc'
      ]);
      return status && processingStatuses.has(status) ? 10000 : false;
    },
  });
}

const EARLY_STATUSES = new Set([
  'created', 'ingesting', 'ai_processing',
  'translating', 'tts_generating', 'rendering_video', 'rendering_qc',
]);

export function useJobDownloads(jobId: string, jobStatus?: string) {
  return useQuery({
    queryKey: ['jobs', jobId, 'downloads'],
    queryFn: () => apiClient.getJobDownloads(jobId),
    enabled: !!jobId && !!jobStatus && !EARLY_STATUSES.has(jobStatus),
    staleTime: 30000, // 30 seconds
    refetchOnWindowFocus: false,
  });
}

export function useJobVttContent(jobId: string, language?: string) {
  return useQuery({
    queryKey: ['jobs', jobId, 'vtt', language || 'source'],
    queryFn: () => apiClient.getJobVttContent(jobId, language),
    enabled: !!jobId,
    staleTime: 30000, // 30 seconds
    refetchOnWindowFocus: false,
  });
}

export function useJobValidation(jobId: string) {
  return useQuery({
    queryKey: ['jobs', jobId, 'validation'],
    queryFn: () => apiClient.validateJobAssets(jobId),
    enabled: !!jobId,
  });
}

// Mutation hooks
export function useCreateJob() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: ({ data, file, onUploadProgress }: { 
      data: JobCreateRequest; 
      file: File; 
      onUploadProgress?: (progressEvent: { loaded: number; total: number }) => void 
    }) =>
      apiClient.createJob(data, file, onUploadProgress),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useUpdateJob() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: Partial<Job> }) =>
      apiClient.updateJob(id, data),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useApproveEnglish() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, notes, tts_preferences, accessible_video_method }: {
      id: string;
      notes?: string;
      tts_preferences?: TTSPreferences;
      accessible_video_method?: AccessibleVideoMethod;
    }) =>
      apiClient.approveSource(id, notes, tts_preferences, accessible_video_method),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useApproveSource() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, notes, tts_preferences, accessible_video_method }: {
      id: string;
      notes?: string;
      tts_preferences?: TTSPreferences;
      accessible_video_method?: AccessibleVideoMethod;
    }) =>
      apiClient.approveSource(id, notes, tts_preferences, accessible_video_method),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useRejectJob() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: ({ id, notes }: { id: string; notes: string }) =>
      apiClient.rejectJob(id, notes),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useCompleteJob() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: ({ id, notes }: { id: string; notes?: string }) =>
      apiClient.completeJob(id, notes),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useUpdateJobVtt() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: VttUpdateRequest }) =>
      apiClient.updateJobVttContent(id, data),
    onSuccess: (_, { id, data }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      if (data.retranslate_languages) {
        // Invalidate all language VTTs since retranslation will refresh them
        queryClient.invalidateQueries({ queryKey: ['jobs', id, 'vtt'] });
      } else {
        queryClient.invalidateQueries({ queryKey: ['jobs', id, 'vtt', data.language || 'source'] });
      }
    },
  });
}

export function useRejectFinalReview() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, notes }: { id: string; notes: string }) =>
      apiClient.rejectFinalReview(id, notes),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useUpdateTTSPreferences() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, tts_preferences }: { id: string; tts_preferences: TTSPreferences }) =>
      apiClient.updateTTSPreferences(id, tts_preferences),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
      // Also invalidate accessible video edit state as TTS is being regenerated
      queryClient.invalidateQueries({ queryKey: ['jobs', id, 'accessible-video'] });
    },
  });
}

export function useDeleteJob() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: (id: string) => apiClient.deleteJob(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useBulkDeleteJobs() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: BulkDeleteRequest) => apiClient.bulkDeleteJobs(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useBulkApproveJobs() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: BulkApproveRequest) => apiClient.bulkApproveJobs(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useAdjustVttTiming() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: ({ id, offsetSeconds, language = 'en', adjustCaptions = true, adjustAudioDescription = true }: { 
      id: string; 
      offsetSeconds: number;
      language?: string;
      adjustCaptions?: boolean;
      adjustAudioDescription?: boolean;
    }) =>
      apiClient.adjustVttTiming(id, {
        offset_seconds: offsetSeconds,
        language,
        adjust_captions: adjustCaptions,
        adjust_audio_description: adjustAudioDescription,
      }),
    onSuccess: (_, { id, language }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs', id, 'vtt', language] });
    },
  });
}

export function useReprocessJob() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: string) => apiClient.reprocessJob(id),
    onSuccess: (_, id) => {
      // Invalidate both the specific job and the jobs list to reflect status changes
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useCloneJob() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: string) => apiClient.cloneJob(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useRetryTts() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: string) => apiClient.retryTts(id),
    onSuccess: (_, id) => {
      // Invalidate both the specific job and the jobs list to reflect status changes
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useRetryJob() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, fromStep }: { id: string; fromStep?: string }) =>
      apiClient.retryJob(id, fromStep),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useCancelJob() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id }: { id: string }) => apiClient.cancelJob(id),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useReturnToQC() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, notes }: { id: string; notes: string }) =>
      apiClient.returnToQC(id, { notes }),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['jobs', id] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useBulkReturnToQC() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: BulkReturnToQCRequest) => apiClient.bulkReturnToQC(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useBriefs() {
  return useQuery({
    queryKey: ['briefs'],
    queryFn: () => apiClient.listBriefs(),
    refetchInterval: 60_000,
  });
}

export function useBrief(id: string) {
  return useQuery({
    queryKey: ['briefs', id],
    queryFn: () => apiClient.getBrief(id),
    enabled: !!id,
  });
}

export function useCreateBrief() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (data: import('../types/api').JobBriefCreate) => apiClient.createBrief(data),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['briefs'] }),
  });
}

export function useSubmitBrief() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => apiClient.submitBrief(id),
    onSuccess: (_, id) => {
      queryClient.invalidateQueries({ queryKey: ['briefs', id] });
      queryClient.invalidateQueries({ queryKey: ['briefs'] });
    },
  });
}

export function useApproveBrief() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => apiClient.approveBrief(id),
    onSuccess: (_, id) => {
      queryClient.invalidateQueries({ queryKey: ['briefs', id] });
      queryClient.invalidateQueries({ queryKey: ['briefs'] });
    },
  });
}

export function useFailures(filters?: { step?: string; org_id?: string; limit?: number; skip?: number }) {
  return useQuery({
    queryKey: ['failures', filters],
    queryFn: () => apiClient.listFailures(filters),
    refetchInterval: 30_000,
  });
}

export function useBulkRetry() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ job_ids, strategy }: { job_ids: string[]; strategy?: 'auto' | 'from_scratch' }) =>
      apiClient.bulkRetry(job_ids, strategy),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['failures'] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

export function useProductionQueueStats() {
  return useQuery({
    queryKey: ['production-queue-stats'],
    queryFn: () => apiClient.getProductionQueueStats(),
    refetchInterval: 10_000,
  });
}

export function useUploadFinalVtt() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({
      jobId, language, vttFile, vttType,
    }: { jobId: string; language: string; vttFile: File; vttType?: 'captions' | 'ad' }) =>
      apiClient.uploadFinalVtt(jobId, language, vttFile, vttType),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['failures'] });
      queryClient.invalidateQueries({ queryKey: ['jobs'] });
    },
  });
}

/** Returns the total count of QC tasks personally assigned to the current user (linguist + reviewer combined). */
export function useMyQCQueueCount(enabled = true) {
  const results = useQueries({
    queries: [
      {
        queryKey: ['linguist-queue', 'linguist', 'all'],
        queryFn: () => apiClient.getMyLanguageQCQueue('linguist'),
        enabled,
        staleTime: 30_000,
        refetchInterval: 30_000,
      },
      {
        queryKey: ['linguist-queue', 'reviewer', 'all'],
        queryFn: () => apiClient.getMyLanguageQCQueue('reviewer'),
        enabled,
        staleTime: 30_000,
        refetchInterval: 30_000,
      },
    ],
  });
  return (results[0].data?.total ?? 0) + (results[1].data?.total ?? 0);
}