import type { AxiosResponse } from 'axios'
import type {
  Result,
  CreateRequestDto,
  RouteRequestDto,
  SaveRequestDto,
  AgreeAutoRequestDto,
  AgreeRequestDto,
  OperateRequestDto,
  StartResponseDto,
  RuntimeRouteNode,
  BaseWorkflowForm
} from '@cacp/ui'

import request from '@/utils/request'

export async function createStart<T extends BaseWorkflowForm>(
  contextPath: string,
  dto: CreateRequestDto
): Promise<Result<StartResponseDto<T>>> {
  const res: AxiosResponse<Promise<Result<StartResponseDto<T>>>> = await request.post(
    `${contextPath}/create-start`,
    dto
  )
  return res.data
}

export async function start<T extends BaseWorkflowForm>(
  contextPath: string,
  taskId: string,
  formId: string
): Promise<Result<StartResponseDto<T>>> {
  const res: AxiosResponse<Promise<Result<StartResponseDto<T>>>> = await request.get(`${contextPath}/start`, {
    params: { taskId: taskId, formId: formId }
  })
  return res.data
}

export async function route(contextPath: string, dto: RouteRequestDto): Promise<Result<Array<RuntimeRouteNode>>> {
  const res: AxiosResponse<Promise<Result<Array<RuntimeRouteNode>>>> = await request.post(`${contextPath}/route`, dto)
  return res.data
}

export async function save<T extends BaseWorkflowForm>(
  contextPath: string,
  dto: SaveRequestDto<T>
): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.post(`${contextPath}/save`, dto)
  return res.data
}

export async function autoAgree<T extends BaseWorkflowForm>(
  contextPath: string,
  dto: AgreeAutoRequestDto<T>
): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.post(`${contextPath}/auto-agree`, dto)
  return res.data
}

export async function agree<T extends BaseWorkflowForm>(
  contextPath: string,
  dto: AgreeRequestDto<T>
): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.post(`${contextPath}/agree`, dto)
  return res.data
}

export async function back<T extends BaseWorkflowForm>(
  contextPath: string,
  dto: OperateRequestDto<T>
): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.post(`${contextPath}/back`, dto)
  return res.data
}

export async function revoke(contextPath: string, taskId: string, formId: string): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.get(`${contextPath}/revoke`, {
    params: { taskId: taskId, formId: formId }
  })
  return res.data
}

export async function reject<T extends BaseWorkflowForm>(
  contextPath: string,
  dto: OperateRequestDto<T>
): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.post(`${contextPath}/reject`, dto)
  return res.data
}

export async function suspend<T extends BaseWorkflowForm>(
  contextPath: string,
  dto: OperateRequestDto<T>
): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.post(`${contextPath}/suspend`, dto)
  return res.data
}

export async function resume(contextPath: string, processId: string, formId: string): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.get(`${contextPath}/resume`, {
    params: { processId: processId, formId: formId }
  })
  return res.data
}

export async function remove(contextPath: string, taskId: string, formId: string): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.post(`${contextPath}/delete`, null, {
    params: { taskId: taskId, formId: formId }
  })
  return res.data
}

export async function forceDelete(contextPath: string, formId: string): Promise<Result<boolean>> {
  const res: AxiosResponse<Promise<Result<boolean>>> = await request.post(`${contextPath}/force-delete`, null, {
    params: { formId: formId }
  })
  return res.data
}

export async function show<T extends BaseWorkflowForm>(
  contextPath: string,
  taskId: string,
  formId: string
): Promise<Result<StartResponseDto<T>>> {
  const res: AxiosResponse<Promise<Result<StartResponseDto<T>>>> = await request.get(`${contextPath}/show`, {
    params: { taskId: taskId, formId: formId }
  })
  return res.data
}
