"use server";

import { cache } from 'react';
import { Pageable, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
import { JobOrder, JoStatus, Machine, Operator } from ".";
import { BASE_API_URL } from "@/config/api";
import { revalidateTag } from "next/cache";
import { convertObjToURLSearchParams } from "@/app/utils/commonUtil";

export interface SaveJo {
  bomId: number;
  planStart: string;
  planEnd: string;
  reqQty: number;
  type: string;
}

export interface SaveJoResponse {
  id: number;
}

export interface SearchJoResultRequest extends Pageable {
  code: string;
  itemName?: string;

}


export interface SearchJoResultResponse {
  records: JobOrder[];
  total: number;
}

// DEPRECIATED
export interface SearchJoResult {
  id: number;
  code: string;
  itemCode: string;
  name: string;
  reqQty: number;
  uom: string;
  status: JoStatus;
}

export interface UpdateJoRequest {
  id: number;
  status: string;
}

// For Jo Button Actions
export interface CommonActionJoRequest {
  id: number;
}

export interface CommonActionJoResponse {
  id: number;
  entity: { status: JoStatus }
}

// For Jo Process
export interface IsOperatorExistResponse<T> {
  id: number | null;
  name: string;
  code: string;
  type?: string;
  message: string | null;
  errorPosition: string | keyof T;
  entity: T;
}

export interface isCorrectMachineUsedResponse<T> {
  id: number | null;
  name: string;
  code: string;
  type?: string;
  message: string | null;
  errorPosition: string | keyof T;
  entity: T;
}

export interface JobOrderDetail {
  id: number;
  code: string;
  name: string;
  reqQty: number;
  uom: string;
  pickLines: any[];
  status: string;
}

export interface UnassignedJobOrderPickOrder {
  pickOrderId: number;
  pickOrderCode: string;
  pickOrderConsoCode: string;
  pickOrderTargetDate: string;
  pickOrderStatus: string;
  jobOrderId: number;
  jobOrderCode: string;
  jobOrderName: string;
  reqQty: number;
  uom: string;
  planStart: string;
  planEnd: string;
}

export interface AssignJobOrderResponse {
  id: number | null;
  code: string | null;
  name: string | null;
  type: string | null;
  message: string | null;
  errorPosition: string | null;
}

export interface PrintPickRecordRequest{
  pickOrderId: number;
  printerId: number;
  printQty: number;
}

export interface PrintPickRecordResponse{
  success: boolean;
  message?: string
}

export const recordSecondScanIssue = cache(async (
  pickOrderId: number,
  itemId: number,
  data: {
    qty: number;
    isMissing: boolean;
    isBad: boolean;
    reason: string;
    createdBy: number;
  }
  
) => {
  return serverFetchJson<any>(
    `${BASE_API_URL}/jo/second-scan-issue/${pickOrderId}/${itemId}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data),
      next: { tags: ["jo-second-scan"] },
    },
  );
});
export const updateSecondQrScanStatus = cache(async (pickOrderId: number, itemId: number) => {
  return serverFetchJson<any>(
    `${BASE_API_URL}/jo/second-scan-qr/${pickOrderId}/${itemId}`,
    {
      method: "POST",
      next: { tags: ["jo-second-scan"] },
    },
  );
});

export const submitSecondScanQuantity = cache(async (
  pickOrderId: number, 
  itemId: number, 
  data: { qty: number; isMissing?: boolean; isBad?: boolean; reason?: string }
) => {
  return serverFetchJson<any>(
    `${BASE_API_URL}/jo/second-scan-submit/${pickOrderId}/${itemId}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data),
      next: { tags: ["jo-second-scan"] },
    },
  );
});
// 获取未分配的 Job Order pick orders
export const fetchUnassignedJobOrderPickOrders = cache(async () => {
  return serverFetchJson<UnassignedJobOrderPickOrder[]>(
    `${BASE_API_URL}/jo/unassigned-job-order-pick-orders`,
    {
      method: "GET",
      next: { tags: ["jo-unassigned"] },
    },
  );
});

// 分配 Job Order pick order 给用户
export const assignJobOrderPickOrder = async (pickOrderId: number, userId: number) => {
  return serverFetchJson<AssignJobOrderResponse>(
    `${BASE_API_URL}/jo/assign-job-order-pick-order/${pickOrderId}/${userId}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
    }
  );
};

// 获取 Job Order 分层数据
export const fetchJobOrderLotsHierarchical = cache(async (userId: number) => {
  return serverFetchJson<any>(
    `${BASE_API_URL}/jo/all-lots-hierarchical/${userId}`,
    {
      method: "GET",
      next: { tags: ["jo-hierarchical"] },
    },
  );
});
export const fetchCompletedJobOrderPickOrders = cache(async (userId: number) => {
  return serverFetchJson<any>(
    `${BASE_API_URL}/jo/completed-job-order-pick-orders/${userId}`,
    {
      method: "GET",
      next: { tags: ["jo-completed"] },
    },
  );
});
// 获取已完成的 Job Order pick orders
export const fetchCompletedJobOrderPickOrdersrecords = cache(async (userId: number) => {
  return serverFetchJson<any>(
    `${BASE_API_URL}/jo/completed-job-order-pick-orders-only/${userId}`,
    {
      method: "GET",
      next: { tags: ["jo-completed"] },
    },
  );
});

// 获取已完成的 Job Order pick order records
export const fetchCompletedJobOrderPickOrderRecords = cache(async (userId: number) => {
  return serverFetchJson<any[]>(
    `${BASE_API_URL}/jo/completed-job-order-pick-order-records/${userId}`,
    {
      method: "GET",
      next: { tags: ["jo-records"] },
    },
  );
});

export const fetchJobOrderDetailByCode = cache(async (code: string) => {
  return serverFetchJson<JobOrderDetail>(
    `${BASE_API_URL}/jo/detailByCode/${code}`,
    {
      method: "GET",
      next: { tags: ["jo"] },
    },
  );
});
export const isOperatorExist = async (username: string) => {
  const isExist = await serverFetchJson<IsOperatorExistResponse<Operator>>(
    `${BASE_API_URL}/jop/isOperatorExist`,
    {
      method: "POST",
      body: JSON.stringify({ username }),
      headers: { "Content-Type": "application/json" },
    },
  );
  revalidateTag("po");
  return isExist;
};

export const isCorrectMachineUsed = async (machineCode: string) => {
  const isExist = await serverFetchJson<isCorrectMachineUsedResponse<Machine>>(
    `${BASE_API_URL}/jop/isCorrectMachineUsed`,
    {
      method: "POST",
      body: JSON.stringify({ machineCode }),
      headers: { "Content-Type": "application/json" },
    },
  );
  revalidateTag("po");
  return isExist;
};


export const fetchJos = cache(async (data?: SearchJoResultRequest) => {
  const queryStr = convertObjToURLSearchParams(data)
  const response = serverFetchJson<SearchJoResultResponse>(
    `${BASE_API_URL}/jo/getRecordByPage?${queryStr}`,
    {
      method: "GET",
      headers: { "Content-Type": "application/json" },
      next: {
        tags: ["jos"]
      }
    }
  )

  return response
})

export const updateJo = cache(async (data: UpdateJoRequest) => {
  return serverFetchJson<SaveJoResponse>(`${BASE_API_URL}/jo/update`,
    {
      method: "POST",
      body: JSON.stringify(data),
      headers: { "Content-Type": "application/json" },
    })
})

export const releaseJo = cache(async (data: CommonActionJoRequest) => {
  const response = serverFetchJson<CommonActionJoResponse>(`${BASE_API_URL}/jo/release`,
    {
      method: "POST",
      body: JSON.stringify(data),
      headers: { "Content-Type": "application/json" },
    })
  
  // Invalidate the cache after releasing
  revalidateTag("jo");
  
  return response;
})

export const startJo = cache(async (data: CommonActionJoRequest) => {
  const response = serverFetchJson<CommonActionJoResponse>(`${BASE_API_URL}/jo/start`,
    {
      method: "POST",
      body: JSON.stringify(data),
      headers: { "Content-Type": "application/json" },
    })
  
  // Invalidate the cache after starting
  revalidateTag("jo");
  
  return response;
})

export const manualCreateJo = cache(async (data: SaveJo) => {
  return serverFetchJson<SaveJoResponse>(`${BASE_API_URL}/jo/manualCreate`, {
    method: "POST",
    body: JSON.stringify(data),
    headers: { "Content-Type": "application/json" }
  })
})

export const fetchCompletedJobOrderPickOrdersWithCompletedSecondScan = cache(async (userId: number) => {
  return serverFetchJson<any[]>(`${BASE_API_URL}/jo/completed-job-order-pick-orders-with-completed-second-scan/${userId}`, {
    method: "GET",
    headers: { "Content-Type": "application/json" }
  })
})
export const fetchCompletedJobOrderPickOrderLotDetails = cache(async (pickOrderId: number) => {
  return serverFetchJson<any[]>(`${BASE_API_URL}/jo/completed-job-order-pick-order-lot-details/${pickOrderId}`, {
    method: "GET",
    headers: { "Content-Type": "application/json" }
  })
})
export const fetchCompletedJobOrderPickOrderLotDetailsForCompletedPick = cache(async (pickOrderId: number) => {  
  return serverFetchJson<any[]>(`${BASE_API_URL}/jo/completed-job-order-pick-order-lot-details-completed-pick/${pickOrderId}`, {
    method: "GET",
    headers: { "Content-Type": "application/json" }
  })
})



export async function PrintPickRecord(request: PrintPickRecordRequest){
  const params = new URLSearchParams();
  params.append('pickOrderId', request.pickOrderId.toString())
  params.append('printerId', request.printerId.toString())
  if (request.printQty !== null && request.printQty !== undefined) {
    params.append('printQty', request.printQty.toString());
  }

  const response = await serverFetchWithNoContent(`${BASE_API_URL}/jo/print-PickRecord?${params.toString()}`,{
    method: "GET"
  });

  return { success: true, message: "Print job sent successfully (Pick Record)" } as PrintPickRecordResponse;
}
