// File: lib/api/ai.ts
// Change Log
// - 2026-05-14: เพิ่ม hooks สำหรับ AI staging queue ตาม ADR-023.
'use client';

import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import apiClient from '@/lib/api/client';

export enum AiStagingStatus {
  PENDING = 'PENDING',
  IMPORTED = 'IMPORTED',
  REJECTED = 'REJECTED',
}

export interface AiStagingRecord {
  publicId: string;
  batchId: string;
  originalFileName: string;
  sourceAttachmentPublicId?: string;
  extractedMetadata?: Record<string, unknown>;
  confidenceScore?: number;
  status: AiStagingStatus;
  errorReason?: string;
  createdAt: string;
  updatedAt: string;
}

export interface AiStagingQueueResponse {
  items: AiStagingRecord[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface ApproveAiStagingPayload {
  documentNumber: string;
  subject: string;
  categoryCode: string;
  projectPublicId: string;
  senderOrganizationPublicId?: string;
  receiverOrganizationPublicId?: string;
  issuedDate?: string;
  receivedDate?: string;
  body?: string;
  finalMetadata?: Record<string, unknown>;
}

interface WrappedData<T> {
  data?: T;
}

export const extractData = <T>(value: unknown): T => {
  let current: unknown = value;
  for (let index = 0; index < 5; index += 1) {
    if (!current || typeof current !== 'object' || !('data' in current)) {
      return current as T;
    }
    current = (current as WrappedData<unknown>).data;
  }
  return current as T;
};

export const aiStagingKeys = {
  all: ['ai-staging'] as const,
  queue: (status?: AiStagingStatus) =>
    [...aiStagingKeys.all, 'queue', status ?? 'ALL'] as const,
};

export function useAiStagingQueue(status?: AiStagingStatus) {
  return useQuery({
    queryKey: aiStagingKeys.queue(status),
    queryFn: async (): Promise<AiStagingQueueResponse> => {
      const response = await apiClient.get('/ai/legacy-migration/queue', {
        params: { status, page: 1, limit: 50 },
      });
      return extractData<AiStagingQueueResponse>(response.data);
    },
    staleTime: 30 * 1000,
  });
}

// ─── RAG Query Hooks (Phase 4) ────────────────────────────────────────────────

export type RagJobStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled' | 'not_found';

export interface AiRagCitation {
  pointId: string | number;
  score: number;
  docType?: string;
  docNumber?: string;
  snippet?: string;
}

export interface AiRagJobResult {
  requestPublicId: string;
  status: RagJobStatus;
  answer?: string;
  citations?: AiRagCitation[];
  confidence?: number;
  usedFallbackModel?: boolean;
  errorMessage?: string;
  completedAt?: string;
}

export interface SubmitRagQueryPayload {
  question: string;
  projectPublicId: string;
}

export const ragQueryKeys = {
  all: ['ai-rag'] as const,
  job: (requestPublicId: string) => [...ragQueryKeys.all, 'job', requestPublicId] as const,
};

export function useSubmitRagQuery() {
  return useMutation({
    mutationFn: async (payload: SubmitRagQueryPayload): Promise<{ requestPublicId: string; jobId: string; status: string }> => {
      const response = await apiClient.post('/ai/rag/query', payload, {
        headers: { 'Idempotency-Key': `rag-${Date.now()}` },
      });
      return extractData<{ requestPublicId: string; jobId: string; status: string }>(response.data);
    },
  });
}

export function useRagJobStatus(requestPublicId: string | null, enabled: boolean) {
  return useQuery({
    queryKey: ragQueryKeys.job(requestPublicId ?? ''),
    queryFn: async (): Promise<AiRagJobResult> => {
      const response = await apiClient.get(`/ai/rag/jobs/${requestPublicId}`);
      return extractData<AiRagJobResult>(response.data);
    },
    enabled: enabled && !!requestPublicId,
    refetchInterval: (query) => {
      const status = query.state.data?.status;
      if (status === 'completed' || status === 'failed' || status === 'cancelled') return false;
      return 2000;
    },
    staleTime: 0,
  });
}

export function useCancelRagJob() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (requestPublicId: string): Promise<void> => {
      await apiClient.delete(`/ai/rag/jobs/${requestPublicId}`);
    },
    onSuccess: (_data, requestPublicId) => {
      void queryClient.invalidateQueries({ queryKey: ragQueryKeys.job(requestPublicId) });
    },
  });
}

export function useApproveAiStagingRecord() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async ({
      publicId,
      payload,
    }: {
      publicId: string;
      payload: ApproveAiStagingPayload;
    }) => {
      const response = await apiClient.post(
        `/ai/legacy-migration/queue/${publicId}/approve`,
        payload
      );
      return extractData<{ record: AiStagingRecord; importResult: unknown }>(
        response.data
      );
    },
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: aiStagingKeys.all });
    },
  });
}

// ─── Phase 6: AI Monitoring & Analytics Hooks (T036, T037) ───────────────────

export interface AiAnalyticsSummary {
  byDocumentType: Array<{
    documentType: string;
    avgConfidence: number;
    overrideRate: number;
    rejectedRate: number;
    total: number;
  }>;
  overall: {
    avgConfidence: number;
    overrideRate: number;
    rejectedRate: number;
    total: number;
  };
}

export const aiAnalyticsKeys = {
  all: ['ai-analytics'] as const,
  summary: () => [...aiAnalyticsKeys.all, 'summary'] as const,
};

export function useAiAnalyticsSummary() {
  return useQuery({
    queryKey: aiAnalyticsKeys.summary(),
    queryFn: async (): Promise<AiAnalyticsSummary> => {
      const response = await apiClient.get('/ai/analytics/summary');
      return extractData<AiAnalyticsSummary>(response.data);
    },
    staleTime: 5 * 60 * 1000, // Analytics can be cached longer
  });
}

export function useDeleteAiAuditLog() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (publicId: string): Promise<{ deleted: boolean; publicId: string }> => {
      const response = await apiClient.delete(`/ai/audit-logs/${publicId}`);
      return extractData<{ deleted: boolean; publicId: string }>(response.data);
    },
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: aiAnalyticsKeys.all });
    },
  });
}
