import { workflowRequestClient } from '#/api/request';

// --- Enums ---

export enum DefinitionStatus {
  Draft = 0,
  Published = 1,
  Disabled = 2,
}

export enum InstanceStatus {
  Pending = 0,
  Running = 1,
  Suspended = 2,
  Completed = 3,
  Terminated = 4,
}

export enum TaskStatus {
  Pending = 0,
  Approved = 1,
  Rejected = 2,
  Transferred = 3,
  Delegated = 4,
}

// --- Types ---

export interface PagedResult<T> {
  items: T[];
  total: number;
  pageIndex: number;
  pageSize: number;
}

export interface WorkflowDefinitionDto {
  id: string;
  name: string;
  code: string;
  description: string | null;
  status: DefinitionStatus;
  version: number;
  definitionJson: string | null;
  isEnabled: boolean;
}

export interface WorkflowInstanceDto {
  id: string;
  definitionId: string;
  title: string;
  status: InstanceStatus;
  initiatorId: string;
  startedAt: string;
  completedAt: string | null;
}

export interface WorkflowTaskListItemDto {
  id: string;
  instanceId: string;
  tokenId: string;
  assigneeId: string | null;
  status: TaskStatus;
  title: string | null;
  completedAt: string | null;
}

export interface WorkflowMonitorDto {
  totalInstances: number;
  runningInstances: number;
  suspendedInstances: number;
  completedInstances: number;
  terminatedInstances: number;
  pendingTasks: number;
  overdueTasks: number;
}

// --- Workflow Definitions ---

export function getWorkflowDefinitionsApi(params?: {
  pageIndex?: number;
  pageSize?: number;
  status?: DefinitionStatus;
}) {
  return workflowRequestClient.get<PagedResult<WorkflowDefinitionDto>>(
    '/workflow-definitions',
    { params },
  );
}

export function createWorkflowDefinitionApi(data: {
  name: string;
  code: string;
  description?: string;
}) {
  return workflowRequestClient.post<WorkflowDefinitionDto>(
    '/workflow-definitions',
    data,
  );
}

export function updateWorkflowDefinitionApi(
  id: string,
  data: { name: string; description?: string; definitionJson?: string },
) {
  return workflowRequestClient.put<WorkflowDefinitionDto>(
    `/workflow-definitions/${id}`,
    data,
  );
}

export function deleteWorkflowDefinitionApi(id: string) {
  return workflowRequestClient.delete(`/workflow-definitions/${id}`);
}

export function publishWorkflowDefinitionApi(id: string) {
  return workflowRequestClient.post(`/workflow-definitions/${id}/publish`);
}

export function disableWorkflowDefinitionApi(id: string) {
  return workflowRequestClient.post(`/workflow-definitions/${id}/disable`);
}

// --- Enums ---

export enum NodeType {
  Start = 0,
  End = 1,
  Approval = 2,
  Cc = 3,
  Condition = 4,
  Parallel = 5,
  SubProcess = 6,
}

export enum EdgeType {
  Normal = 0,
  Approved = 1,
  Rejected = 2,
}

// --- Types ---

export interface WorkflowNodeDto {
  id: string;
  nodeType: NodeType;
  name: string;
  config: string | null;
  positionX: number;
  positionY: number;
}

export interface WorkflowEdgeDto {
  id: string;
  sourceNodeId: string;
  targetNodeId: string;
  edgeType: EdgeType;
  label: string | null;
  condition: string | null;
  order: number;
}

export interface WorkflowDefinitionDetailDto extends WorkflowDefinitionDto {
  nodes: WorkflowNodeDto[];
  edges: WorkflowEdgeDto[];
}

// --- Definition Detail ---

export function getWorkflowDefinitionDetailApi(id: string) {
  return workflowRequestClient.get<WorkflowDefinitionDetailDto>(
    `/workflow-definitions/${id}`,
  );
}

// --- Workflow Nodes ---

export function createNodeApi(
  definitionId: string,
  data: {
    nodeType: NodeType;
    name: string;
    config?: string;
    positionX: number;
    positionY: number;
  },
) {
  return workflowRequestClient.post<WorkflowNodeDto>(
    `/workflow-definitions/${definitionId}/nodes`,
    data,
  );
}

export function updateNodeApi(
  definitionId: string,
  nodeId: string,
  data: {
    name: string;
    config?: string;
    positionX: number;
    positionY: number;
  },
) {
  return workflowRequestClient.put<WorkflowNodeDto>(
    `/workflow-definitions/${definitionId}/nodes/${nodeId}`,
    data,
  );
}

export function deleteNodeApi(definitionId: string, nodeId: string) {
  return workflowRequestClient.delete(
    `/workflow-definitions/${definitionId}/nodes/${nodeId}`,
  );
}

// --- Workflow Edges ---

export function createEdgeApi(
  definitionId: string,
  data: {
    sourceNodeId: string;
    targetNodeId: string;
    edgeType: EdgeType;
    label?: string;
    condition?: string;
    order: number;
  },
) {
  return workflowRequestClient.post<WorkflowEdgeDto>(
    `/workflow-definitions/${definitionId}/edges`,
    data,
  );
}

export function updateEdgeApi(
  definitionId: string,
  edgeId: string,
  data: {
    edgeType: EdgeType;
    label?: string;
    condition?: string;
    order: number;
  },
) {
  return workflowRequestClient.put<WorkflowEdgeDto>(
    `/workflow-definitions/${definitionId}/edges/${edgeId}`,
    data,
  );
}

export function deleteEdgeApi(definitionId: string, edgeId: string) {
  return workflowRequestClient.delete(
    `/workflow-definitions/${definitionId}/edges/${edgeId}`,
  );
}

// --- Workflow Instances ---

export function getWorkflowInstancesApi(params?: {
  pageIndex?: number;
  pageSize?: number;
  status?: InstanceStatus;
  initiatorId?: string;
}) {
  return workflowRequestClient.get<PagedResult<WorkflowInstanceDto>>(
    '/workflow-instances',
    { params },
  );
}

export function startWorkflowInstanceApi(data: {
  definitionCode: string;
  title: string;
  variables?: string;
}) {
  return workflowRequestClient.post<string>('/workflow-instances', data);
}

export function suspendWorkflowInstanceApi(id: string) {
  return workflowRequestClient.post(`/workflow-instances/${id}/suspend`);
}

export function resumeWorkflowInstanceApi(id: string) {
  return workflowRequestClient.post(`/workflow-instances/${id}/resume`);
}

export function withdrawWorkflowInstanceApi(id: string, userId: string) {
  return workflowRequestClient.post(`/workflow-instances/${id}/withdraw`, { userId });
}

export function getWorkflowMonitorApi() {
  return workflowRequestClient.get<WorkflowMonitorDto>('/workflow-instances/monitor');
}

// --- Workflow Tasks ---

export function getPendingTasksApi(params?: {
  userId?: string;
  pageIndex?: number;
  pageSize?: number;
}) {
  return workflowRequestClient.get<PagedResult<WorkflowTaskListItemDto>>(
    '/workflow-tasks/pending',
    { params },
  );
}

export function getHistoryTasksApi(params?: {
  userId?: string;
  pageIndex?: number;
  pageSize?: number;
}) {
  return workflowRequestClient.get<PagedResult<WorkflowTaskListItemDto>>(
    '/workflow-tasks/history',
    { params },
  );
}

export function getOverdueTasksApi(params?: {
  userId?: string;
  pageIndex?: number;
  pageSize?: number;
}) {
  return workflowRequestClient.get<PagedResult<WorkflowTaskListItemDto>>(
    '/workflow-tasks/overdue',
    { params },
  );
}

export function approveTaskApi(id: string, userId: string, comment?: string) {
  return workflowRequestClient.post(`/workflow-tasks/${id}/approve`, { userId, comment });
}

export function rejectTaskApi(id: string, userId: string, comment?: string) {
  return workflowRequestClient.post(`/workflow-tasks/${id}/reject`, { userId, comment });
}

export function delegateTaskApi(
  id: string,
  fromUserId: string,
  toUserId: string,
) {
  return workflowRequestClient.post(`/workflow-tasks/${id}/delegate`, {
    fromUserId,
    toUserId,
  });
}

export function transferTaskApi(
  id: string,
  fromUserId: string,
  toUserId: string,
) {
  return workflowRequestClient.post(`/workflow-tasks/${id}/transfer`, {
    fromUserId,
    toUserId,
  });
}
