import { request } from "./request";
import type { PageResult } from "./basic-data";

export interface Mps {
  id?: number;
  code?: string;
  status?: number;
  saleOrderId?: number;
  saleOrderNo?: string;
  saleOrderItemId?: number;
  productId?: number;
  productCode?: string;
  productName?: string;
  productSpecification?: string;
  unitMeasureId?: number;
  unitMeasureName?: string;
  quantity?: number;
  quantityProduced?: number;
  clientId?: number;
  clientCode?: string;
  clientName?: string;
  requestDate?: string;
  issueDate?: string;
  finishDate?: string;
  workOrderId?: number;
  workOrderCode?: string;
  mergeFlag?: number;
  mergeBatchNo?: string;
  remark?: string;
  createTime?: string;
}

export interface WorkOrder {
  id?: number;
  parentId?: number;
  parentCode?: string;
  code?: string;
  name?: string;
  type?: number;
  orderSourceType?: number;
  orderSourceCode?: string;
  productId?: number;
  productCode?: string;
  productName?: string;
  productSpecification?: string;
  unitMeasureName?: string;
  quantity?: number;
  quantityProduced?: number;
  quantityChanged?: number;
  quantityScheduled?: number;
  clientId?: number;
  clientCode?: string;
  clientName?: string;
  vendorId?: number;
  vendorCode?: string;
  vendorName?: string;
  batchCode?: string;
  requestDate?: string;
  finishDate?: string;
  cancelDate?: string;
  status?: number;
  scheduleStatus?: number;
  productionStatus?: number;
  completionProgress?: number;
  progressPercent?: number;
  feedbackApprove?: boolean;
  processDefinitionKey?: string;
  feedbackRole?: string;
  routeId?: number;
  processProgressList?: Array<{ processName?: string; progress?: number; progressPercent?: number }>;
  remark?: string;
  createTime?: string;
}

export interface WorkOrderProcess {
  id?: number;
  workOrderId?: number;
  processId?: number;
  sort?: number;
  processCode?: string;
  processName?: string;
  paramTemplateId?: number;
  nextProcessId?: number;
  nextProcessName?: string;
  linkType?: number;
  prepareTime?: number;
  waitTime?: number;
  colorCode?: string;
  keyFlag?: boolean;
  checkFlag?: boolean;
  backflushFlag?: boolean;
  outputItemId?: number;
  outputItemCode?: string;
  outputItemName?: string;
  outputItemIds?: number[];
  outputItemNames?: string;
  bomItems?: ProcessBomItem[];
  remark?: string;
}

export interface ProcessBomItem {
  itemId?: number;
  itemCode?: string;
  itemName?: string;
  quantity?: number;
  remark?: string;
}

export interface WorkOrderBom {
  id?: number;
  workOrderId?: number;
  itemCode?: string;
  itemName?: string;
  itemSpecification?: string;
  unitMeasureName?: string;
  itemOrProduct?: number;
  quantity?: number;
}

export interface ApproveProcess {
  id?: string;
  key?: string;
  name?: string;
}

export interface ProProcess {
  id?: number;
  code?: string;
  name?: string;
  status?: number;
}

export interface ProTask {
  id?: number;
  code?: string;
  name?: string;
  workOrderId?: number;
  workOrderCode?: string;
  workOrderName?: string;
  workstationId?: number;
  workstationCode?: string;
  workstationName?: string;
  routeId?: number;
  processId?: number;
  paramTemplateId?: number;
  processName?: string;
  itemId?: number;
  itemCode?: string;
  itemName?: string;
  itemSpecification?: string;
  unitMeasureId?: number;
  unitMeasureName?: string;
  quantity?: number;
  producedQuantity?: number;
  progress?: number;
  progressPercent?: number;
  qualifyQuantity?: number;
  unqualifyQuantity?: number;
  changedQuantity?: number;
  clientId?: number;
  clientName?: string;
  startTime?: string;
  endTime?: string;
  duration?: number;
  requestDate?: string;
  finishDate?: string;
  cancelDate?: string;
  colorCode?: string;
  status?: number;
  checkFlag?: boolean;
  backflushFlag?: boolean;
  remark?: string;
  reportableQuantity?: number;
  assigneeUserIds?: number[];
  feedbackApprove?: boolean;
  createTime?: string;
}

export interface FeedbackParamValue {
  detailId?: number;
  value?: string;
  paramCode?: string;
  paramName?: string;
  paramType?: number;
  unitMeasureName?: string;
  paramValue?: string;
  required?: boolean;
}

export interface ProFeedback {
  id?: number;
  code?: string;
  type?: number;
  channel?: string;
  feedbackTime?: string;
  workstationId?: number;
  workstationCode?: string;
  workstationName?: string;
  routeId?: number;
  routeCode?: string;
  processId?: number;
  processCode?: string;
  processName?: string;
  checkFlag?: boolean;
  workOrderId?: number;
  workOrderCode?: string;
  workOrderName?: string;
  taskId?: number;
  taskCode?: string;
  itemId?: number;
  itemCode?: string;
  itemName?: string;
  itemSpecification?: string;
  unitMeasureId?: number;
  unitMeasureName?: string;
  scheduledQuantity?: number;
  reportableQuantity?: number;
  feedbackQuantity?: number;
  qualifiedQuantity?: number;
  unqualifiedQuantity?: number;
  uncheckQuantity?: number;
  laborScrapQuantity?: number;
  materialScrapQuantity?: number;
  otherScrapQuantity?: number;
  feedbackUserId?: number;
  feedbackUserNickname?: string;
  approveUserId?: number;
  approveUserNickname?: string;
  status?: number;
  remark?: string;
  creator?: string;
  createTime?: string;
  processInstanceId?: string;
  processDefinitionKey?: string;
  paramValues?: FeedbackParamValue[];
}

export interface FeedbackBatchRequirement {
  needBatchInput?: boolean;
  isBatchManaged?: boolean;
  produceDateFlag?: boolean;
  expireDateFlag?: boolean;
  receiptDateFlag?: boolean;
  vendorFlag?: boolean;
  clientFlag?: boolean;
  salesOrderCodeFlag?: boolean;
  purchaseOrderCodeFlag?: boolean;
  workOrderFlag?: boolean;
  taskFlag?: boolean;
  workstationFlag?: boolean;
  toolFlag?: boolean;
  moldFlag?: boolean;
  lotNumberFlag?: boolean;
  qualityStatusFlag?: boolean;
  autoFilledFields?: string[];
}

export interface WorkOrderParamRecordDetail {
  id?: number;
  templateDetailId?: number;
  paramCode?: string;
  paramName?: string;
  paramType?: number;
  unitMeasureId?: number;
  unitMeasureName?: string;
  paramValue?: string;
  required?: boolean;
  remark?: string;
}

export interface WorkOrderParamRecord {
  id?: number;
  workOrderId?: number;
  templateId?: number;
  templateCode?: string;
  templateName?: string;
  recordNo?: string;
  remark?: string;
  createTime?: string;
  details?: WorkOrderParamRecordDetail[];
}

export interface WorkRecordLog {
  id?: number;
  userId?: number;
  userNickname?: string;
  workstationId?: number;
  workstationCode?: string;
  workstationName?: string;
  type?: number;
  remark?: string;
  createTime?: string;
}

export interface MyWorkRecord {
  userId?: number;
  userNickname?: string;
  workstationId?: number;
  workstationCode?: string;
  workstationName?: string;
  type?: number;
  clockInTime?: string;
  clockOutTime?: string;
}

function header(accessToken: string) {
  return { Authorization: `Bearer ${accessToken}` };
}

function query(params: Record<string, string | number | boolean | Array<string | number | boolean> | undefined>) {
  const content = Object.entries(params)
    .filter(([, value]) => value !== undefined && value !== "")
    .flatMap(([key, value]) => Array.isArray(value)
      ? value.map(item => `${encodeURIComponent(key)}=${encodeURIComponent(String(item))}`)
      : `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
    .join("&");
  return content ? `?${content}` : "";
}

export function getMpsPage(accessToken: string, params: { pageNo: number; pageSize: number; code?: string; saleOrderNo?: string; productId?: number; clientId?: number; status?: number }) {
  return request<PageResult<Mps>>(`/mes/pro-mps/page${query(params)}`, { header: header(accessToken) });
}
export function getMps(accessToken: string, id: number) {
  return request<Mps>(`/mes/pro-mps/get${query({ id })}`, { header: header(accessToken) });
}
export function createMps(accessToken: string, data: Mps) {
  return request<number>("/mes/pro-mps/create", { method: "POST", data, header: header(accessToken) });
}
export function updateMps(accessToken: string, data: Mps) {
  return request<boolean>("/mes/pro-mps/update", { method: "PUT", data, header: header(accessToken) });
}
export function deleteMps(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro-mps/delete${query({ id })}`, { method: "DELETE", header: header(accessToken) });
}
export function issueMps(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro-mps/issue${query({ id })}`, { method: "POST", header: header(accessToken) });
}
export function mergeIssueMps(accessToken: string, ids: number[]) {
  return request<boolean>("/mes/pro-mps/merge-issue", { method: "POST", data: ids, header: header(accessToken) });
}
export function cancelMps(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro-mps/cancel${query({ id })}`, { method: "POST", header: header(accessToken) });
}

export function getWorkOrderPage(accessToken: string, params: { pageNo: number; pageSize: number; code?: string; name?: string; orderSourceCode?: string; productId?: number; clientId?: number; status?: number; type?: number }) {
  return request<PageResult<WorkOrder>>(`/mes/pro/work-order/page${query(params)}`, { header: header(accessToken) });
}
export function getWorkOrderSchedulePage(accessToken: string, params: { pageNo: number; pageSize: number; code?: string; name?: string; scheduleStatus?: number; type?: number }) {
  return request<PageResult<WorkOrder>>(`/mes/pro/work-order/schedule-page${query(params)}`, { header: header(accessToken) });
}
export function getWorkOrder(accessToken: string, id: number) {
  return request<WorkOrder>(`/mes/pro/work-order/get${query({ id })}`, { header: header(accessToken) });
}
export function createWorkOrder(accessToken: string, data: WorkOrder) {
  return request<number>("/mes/pro/work-order/create", { method: "POST", data, header: header(accessToken) });
}
export function updateWorkOrder(accessToken: string, data: WorkOrder) {
  return request<boolean>("/mes/pro/work-order/update", { method: "PUT", data, header: header(accessToken) });
}
export function deleteWorkOrder(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro/work-order/delete${query({ id })}`, { method: "DELETE", header: header(accessToken) });
}
export function finishWorkOrder(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro/work-order/finish${query({ id })}`, { method: "PUT", header: header(accessToken) });
}
export function cancelWorkOrder(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro/work-order/cancel${query({ id })}`, { method: "PUT", header: header(accessToken) });
}
export function confirmWorkOrder(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro/work-order/confirm${query({ id })}`, { method: "PUT", header: header(accessToken) });
}
export function getWorkOrderApproveProcessList(accessToken: string) {
  return request<ApproveProcess[]>("/mes/pro/work-order/approve-process-list", { header: header(accessToken) });
}
export function getWorkOrderProcessListByWorkOrderId(accessToken: string, workOrderId: number) {
  return request<WorkOrderProcess[]>(`/mes/pro/work-order-process/list-by-work-order-id${query({ workOrderId })}`, { header: header(accessToken) });
}
export function getRouteProcessListByProduct(accessToken: string, productId: number) {
  return request<WorkOrderProcess[]>(`/mes/pro/route-process/list-by-product${query({ productId })}`, { header: header(accessToken) });
}
export function getProcessSimpleList(accessToken: string) {
  return request<ProProcess[]>("/mes/pro/process/simple-list", { header: header(accessToken) });
}
export function getWorkOrderProcess(accessToken: string, id: number) {
  return request<WorkOrderProcess>(`/mes/pro/work-order-process/get${query({ id })}`, { header: header(accessToken) });
}
export function createWorkOrderProcess(accessToken: string, data: WorkOrderProcess) {
  return request<number>("/mes/pro/work-order-process/create", { method: "POST", data, header: header(accessToken) });
}
export function updateWorkOrderProcess(accessToken: string, data: WorkOrderProcess) {
  return request<boolean>("/mes/pro/work-order-process/update", { method: "PUT", data, header: header(accessToken) });
}
export function deleteWorkOrderProcess(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro/work-order-process/delete${query({ id })}`, { method: "DELETE", header: header(accessToken) });
}
export function batchSaveWorkOrderProcess(accessToken: string, data: WorkOrderProcess[]) {
  return request<boolean>("/mes/pro/work-order-process/batch-save", { method: "POST", data, header: header(accessToken) });
}
export function getWorkOrderBomList(accessToken: string, workOrderId: number) {
  return request<WorkOrderBom[]>(`/mes/pro/work-order-bom/item-list-by-work-order-id${query({ workOrderId })}`, { header: header(accessToken) });
}

export function getTaskPage(accessToken: string, params: { pageNo: number; pageSize: number; code?: string; name?: string; workOrderId?: number; workstationId?: number; routeId?: number; processId?: number; status?: number; statuses?: number[] }) {
  return request<PageResult<ProTask>>(`/mes/pro/task/page${query(params)}`, { header: header(accessToken) });
}
export function getTask(accessToken: string, id: number) {
  return request<ProTask>(`/mes/pro/task/get${query({ id })}`, { header: header(accessToken) });
}
export function createTask(accessToken: string, data: ProTask) {
  return request<number>("/mes/pro/task/create", { method: "POST", data, header: header(accessToken) });
}
export function updateTask(accessToken: string, data: ProTask) {
  return request<boolean>("/mes/pro/task/update", { method: "PUT", data, header: header(accessToken) });
}
export function deleteTask(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro/task/delete${query({ id })}`, { method: "DELETE", header: header(accessToken) });
}
export function getGanttTaskList(accessToken: string, params: { status?: number; type?: number }) {
  return request<ProTask[]>(`/mes/pro/task/gantt-list${query(params)}`, { header: header(accessToken) });
}
export function calculateTaskDuration(accessToken: string, workstationId: number, quantity: number) {
  return request<{ duration: number }>(`/mes/pro/task/calculate-duration${query({ workstationId, quantity })}`, { header: header(accessToken) });
}
export function pauseTask(accessToken: string, data: { id: number; reason: string; remark?: string }) {
  return request<boolean>("/mes/pro/task/pause", { method: "PUT", data, header: header(accessToken) });
}
export function resumeTask(accessToken: string, data: { id: number }) {
  return request<boolean>("/mes/pro/task/resume", { method: "PUT", data, header: header(accessToken) });
}

export interface BatchScheduleRequest {
  workOrderIds: number[]; startTime: string; previewHash?: string; previewTime?: string; allowLate?: boolean;
}
export interface BatchSchedulePreview {
  canExecute: boolean; previewHash: string; previewTime: string; warnings: string[];
  orders: Array<{ workOrderId: number; workOrderCode?: string; taskCount: number; endTime?: string; late: boolean; error?: string }>;
  tasks: Array<{ workOrderId: number; processId: number; processName: string; workstationName: string; quantity: number; startTime: string; endTime: string }>;
}
export function previewBatchSchedule(accessToken: string, data: BatchScheduleRequest) {
  return request<BatchSchedulePreview>("/mes/pro/task/auto-schedule/preview", { method: "POST", data, header: header(accessToken) });
}
export function executeBatchSchedule(accessToken: string, data: BatchScheduleRequest) {
  return request<{ taskIds: number[] }>("/mes/pro/task/auto-schedule", { method: "POST", data, header: header(accessToken) });
}

export function getFeedbackPage(accessToken: string, params: { pageNo: number; pageSize: number; code?: string; type?: number; workOrderId?: number; taskId?: number; itemId?: number; feedbackUserId?: number; creator?: string; status?: number }) {
  return request<PageResult<ProFeedback>>(`/mes/pro/feedback/page${query(params)}`, { header: header(accessToken) });
}
export function getFeedback(accessToken: string, id: number) {
  return request<ProFeedback>(`/mes/pro/feedback/get${query({ id })}`, { header: header(accessToken) });
}
export function createFeedback(accessToken: string, data: ProFeedback) {
  return request<number>("/mes/pro/feedback/create", { method: "POST", data, header: header(accessToken) });
}
export function updateFeedback(accessToken: string, data: ProFeedback) {
  return request<boolean>("/mes/pro/feedback/update", { method: "PUT", data, header: header(accessToken) });
}
export function deleteFeedback(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro/feedback/delete${query({ id })}`, { method: "DELETE", header: header(accessToken) });
}
export function submitFeedback(accessToken: string, data: { id: number; [key: string]: unknown }) {
  return request<boolean>("/mes/pro/feedback/submit", { method: "PUT", data, header: header(accessToken) });
}
export function rejectFeedback(accessToken: string, id: number) {
  return request<boolean>(`/mes/pro/feedback/reject${query({ id })}`, { method: "PUT", header: header(accessToken) });
}
export function approveFeedback(accessToken: string, data: { id: number; [key: string]: unknown }) {
  return request<boolean>("/mes/pro/feedback/approve", { method: "PUT", data, header: header(accessToken) });
}
export function getBatchRequirements(accessToken: string, id: number) {
  return request<FeedbackBatchRequirement>(`/mes/pro/feedback/batch-requirements${query({ id })}`, { header: header(accessToken) });
}
export function getFeedbackListByTask(accessToken: string, taskId: number) {
  return request<ProFeedback[]>(`/mes/pro/feedback/list-by-task${query({ taskId })}`, { header: header(accessToken) });
}

export function getWorkOrderParamRecordPage(accessToken: string, params: { pageNo: number; pageSize: number; taskId?: number; workstationId?: number; recordNo?: string; templateName?: string }) {
  return request<PageResult<WorkOrderParamRecord>>(`/mes/pro/work-order-param-record/page-by-work-order${query(params)}`, { header: header(accessToken) });
}

export function getWorkRecordLogPage(accessToken: string, params: { pageNo: number; pageSize: number; userId?: number; workstationId?: number; type?: number }) {
  return request<PageResult<WorkRecordLog>>(`/mes/pro/workrecord/log/page${query(params)}`, { header: header(accessToken) });
}
export function getWorkRecordLog(accessToken: string, id: number) {
  return request<WorkRecordLog>(`/mes/pro/workrecord/log/get${query({ id })}`, { header: header(accessToken) });
}
export function clockInWorkRecord(accessToken: string, workstationId: number) {
  return request<boolean>(`/mes/pro/workrecord/clock-in${query({ workstationId })}`, { method: "PUT", header: header(accessToken) });
}
export function clockOutWorkRecord(accessToken: string) {
  return request<boolean>("/mes/pro/workrecord/clock-out", { method: "PUT", header: header(accessToken) });
}
export function getMyWorkRecord(accessToken: string) {
  return request<MyWorkRecord>("/mes/pro/workrecord/get-my", { header: header(accessToken) });
}
