import { del, get, post, put } from '../request'
import type {
  DataProcessExternalSourcePayload,
  DataProcessExternalTestResult,
  DataProcessPage,
  DataProcessOfficePreview,
  DataProcessPdfPages,
  DataProcessPreviewBuildPayload,
  DataProcessPreviewBuildResult,
  DataProcessPreviewCreatePayload,
  DataProcessPreviewItem,
  DataProcessPreviewUpdatePayload,
  DataProcessProgress,
  DataProcessRegeneratePayload,
  DataProcessRegenerateResult,
  DataProcessPublishPayload,
  DataProcessPublishResult,
  DataProcessQualityScore,
  DataProcessResult,
  DataProcessResultUpdatePayload,
  DataProcessSourceContent,
  DataProcessSourceFile,
  DataProcessTask,
  DataProcessTaskCreatePayload,
  DataProcessTaskUpdatePayload,
} from '@/types/dataProcess'

export type {
  DataProcessConfig,
  DataProcessDatasetSplit,
  DataProcessExternalSourcePayload,
  DataProcessExternalTestResult,
  DataProcessPage,
  DataProcessDocxParagraph,
  DataProcessDocxPreview,
  DataProcessDocxTable,
  DataProcessDocxTableRow,
  DataProcessOfficePreview,
  DataProcessPdfPageRange,
  DataProcessPdfPages,
  DataProcessPreviewBuildPayload,
  DataProcessPreviewBuildFileResult,
  DataProcessPreviewBuildResult,
  DataProcessPreviewFileBuildProgress,
  DataProcessPreviewFileStatus,
  DataProcessPreviewCreatePayload,
  DataProcessPreviewItem,
  DataProcessPreviewUpdatePayload,
  DataProcessProgress,
  DataProcessRegeneratePayload,
  DataProcessRegenerateResult,
  DataProcessPublishPayload,
  DataProcessPublishResult,
  DataProcessQualityScore,
  DataProcessResult,
  DataProcessResultStatus,
  DataProcessResultUpdatePayload,
  DataProcessSplit,
  DataProcessSourceContent,
  DataProcessSourceFile,
  DataProcessStatus,
  DataProcessTask,
  DataProcessTaskCreatePayload,
  DataProcessTaskUpdatePayload,
  DataProcessType,
  DataProcessXlsxActiveSheet,
  DataProcessXlsxPreview,
  DataProcessXlsxPreviewRow,
  DataProcessXlsxSheet,
} from '@/types/dataProcess'

export function getDataProcessTasks(params: {
  page?: number
  page_size?: number
  keyword?: string
  status?: string
  process_type?: string
} = {}) {
  return get<DataProcessPage<DataProcessTask>>('/data-process', params)
}

export const getDataProcessTask = (taskId: string | number) =>
  get<DataProcessTask>(`/data-process/${encodeURIComponent(taskId)}`)

export const createDataProcessTask = (payload: DataProcessTaskCreatePayload) =>
  post<DataProcessTask>(`/data-process`, payload)

export const updateDataProcessTask = (taskId: string | number, payload: DataProcessTaskUpdatePayload) =>
  put<DataProcessTask>(`/data-process/${encodeURIComponent(taskId)}`, payload)

export const regenerateDataProcessTask = (
  taskId: string | number,
  payload: DataProcessRegeneratePayload,
) => post<DataProcessRegenerateResult>(
  `/data-process/${encodeURIComponent(taskId)}/regenerate`,
  payload,
)

export const deleteDataProcessTask = (taskId: string | number) =>
  del<{ deleted: string | number }>(`/data-process/${encodeURIComponent(taskId)}`)

export function uploadDataProcessSourceFiles(
  taskId: string | number,
  files: File[],
  onProgress?: (progress: number) => void,
) {
  const formData = new FormData()
  files.forEach((file) => formData.append('files', file))
  return post<{ files: DataProcessSourceFile[] }>(
    `/data-process/${encodeURIComponent(taskId)}/source-files`,
    formData,
    {
      timeout: 5 * 60 * 1000,
      onUploadProgress: (event) => {
        if (!event.total) return
        // 发送完成不等于服务端解析完成；收到成功响应前最多展示 99%。
        const progress = Math.round((event.loaded / event.total) * 100)
        onProgress?.(Math.min(99, Math.max(0, progress)))
      },
    },
  )
}

export const deleteDataProcessSourceFile = (taskId: string | number, fileId: string | number) =>
  del<{ deleted: string | number }>(
    `/data-process/${encodeURIComponent(taskId)}/source-files/${encodeURIComponent(fileId)}`,
  )

export const getDataProcessSourceContent = (
  taskId: string | number,
  fileId: string | number,
  params: { start_line?: number; line_count?: number } = {},
) => get<DataProcessSourceContent>(
  `/data-process/${encodeURIComponent(taskId)}/source-files/${encodeURIComponent(fileId)}/content`,
  params,
)

export const getDataProcessSourceRawUrl = (
  taskId: string | number,
  fileId: string | number,
) => `/modelTF/data-process/${encodeURIComponent(taskId)}/source-files/${encodeURIComponent(fileId)}/raw`

export const getDataProcessPdfPages = (
  taskId: string | number,
  fileId: string | number,
) => get<DataProcessPdfPages>(
  `/data-process/${encodeURIComponent(taskId)}/source-files/${encodeURIComponent(fileId)}/pdf-pages`,
)

export const getDataProcessOfficePreview = (
  taskId: string | number,
  fileId: string | number,
  params: { sheet_index?: number; offset?: number; limit?: number } = {},
) => get<DataProcessOfficePreview>(
  `/data-process/${encodeURIComponent(taskId)}/source-files/${encodeURIComponent(fileId)}/office-preview`,
  params,
  { timeout: 60_000 },
)

export const testDataProcessExternalSource = (
  taskId: string | number,
  payload: DataProcessExternalSourcePayload,
) => {
  const { query: _query, file_name: _fileName, ...connection } = payload
  return post<DataProcessExternalTestResult>(
    `/data-process/${encodeURIComponent(taskId)}/external/test`,
    connection,
  )
}

export const pullDataProcessExternalSource = (
  taskId: string | number,
  payload: DataProcessExternalSourcePayload,
) => post<{ files: DataProcessSourceFile[] }>(
  `/data-process/${encodeURIComponent(taskId)}/external/pull`,
  payload,
)

export const buildDataProcessPreview = (
  taskId: string | number,
  payload: DataProcessPreviewBuildPayload = {},
) => post<DataProcessPreviewBuildResult>(
  `/data-process/${encodeURIComponent(taskId)}/preview/build`,
  payload,
  { timeout: 5 * 60 * 1000 },
)

export function getDataProcessPreview(
  taskId: string | number,
  params: { source_file_id?: string | number; page?: number; page_size?: number; keyword?: string } = {},
) {
  return get<DataProcessPage<DataProcessPreviewItem>>(
    `/data-process/${encodeURIComponent(taskId)}/preview`,
    params,
  )
}

export const updateDataProcessPreview = (
  taskId: string | number,
  previewId: string | number,
  payload: DataProcessPreviewUpdatePayload,
) => put<DataProcessPreviewItem>(
  `/data-process/${encodeURIComponent(taskId)}/preview/${encodeURIComponent(previewId)}`,
  payload,
)

export const createDataProcessPreview = (
  taskId: string | number,
  payload: DataProcessPreviewCreatePayload,
) => post<DataProcessPreviewItem>(`/data-process/${encodeURIComponent(taskId)}/preview`, payload)

export const deleteDataProcessPreview = (
  taskId: string | number,
  previewId: string | number,
) => del<Record<string, never>>(
  `/data-process/${encodeURIComponent(taskId)}/preview/${encodeURIComponent(previewId)}`,
)

export const generateDataProcess = (taskId: string | number) =>
  post<DataProcessProgress>(`/data-process/${encodeURIComponent(taskId)}/generate`)

export const stopDataProcess = (taskId: string | number) =>
  post<DataProcessProgress>(`/data-process/${encodeURIComponent(taskId)}/stop`)

export const getDataProcessProgress = (taskId: string | number) =>
  get<DataProcessProgress>(`/data-process/${encodeURIComponent(taskId)}/progress`)

export function getDataProcessResults(
  taskId: string | number,
  params: { page?: number; page_size?: number; keyword?: string; status?: string; split?: string } = {},
) {
  return get<DataProcessPage<DataProcessResult>>(
    `/data-process/${encodeURIComponent(taskId)}/results`,
    params,
  )
}

export const updateDataProcessResult = (
  taskId: string | number,
  resultId: string | number,
  payload: DataProcessResultUpdatePayload,
) => put<DataProcessResult>(
  `/data-process/${encodeURIComponent(taskId)}/results/${encodeURIComponent(resultId)}`,
  payload,
)

export const restoreDataProcessResult = (taskId: string | number, resultId: string | number) =>
  post<DataProcessResult>(
    `/data-process/${encodeURIComponent(taskId)}/results/${encodeURIComponent(resultId)}/restore`,
  )

export const publishDataProcess = (taskId: string | number, payload: DataProcessPublishPayload) =>
  post<DataProcessPublishResult>(`/data-process/${encodeURIComponent(taskId)}/publish`, payload)
