"use server";
import { BASE_API_URL } from "@/config/api";
// import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
import { revalidateTag } from "next/cache";
import { cache } from "react";
import { serverFetch, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
import { QcItemResult } from "../settings/qcItem";
import { RecordsRes } from "../utils";
import { DoResult } from ".";
import { GridRowId, GridRowSelectionModel } from "@mui/x-data-grid";
import { GET } from "../auth/[...nextauth]/route";
import { stringify } from "querystring";
import { convertObjToURLSearchParams } from "@/app/utils/commonUtil";
export interface CreateConsoDoInput {
  ids: GridRowSelectionModel;
}
export interface DoDetail {
  id: number;
  code: string;
  supplierCode: string;
  shopCode: string;
  shopName: string;
  currencyCode: string;
  orderDate: string;
  estimatedArrivalDate: string;
  completeDate: string;
  status: string;
  /** 加單 DO */
  isExtra?: boolean;
  deliveryOrderLines: DoDetailLine[];
}

export interface DoDetailLine {
  id: number;
  itemNo: string;
  qty: number;
  price: number;
  status: string;
  itemName?: string;
  uomCode?: string;
  uom?: string;
  shortUom?: string;
  /** AVAILABLE lot lines: sum(in - out - hold), same unit as DO line qty. */
  stockQty?: number;
  /** `available` | `insufficient` */
  availableStatus?: string;
}

export interface DoSearchAll {
  id: number;
  code: string;
  status: string;
  estimatedArrivalDate: number[]; 
  orderDate: number[]; 
  supplierName: string;
  shopName: string;
  shopAddress?: string; 
  isExtra?: boolean;
}
export interface DoSearchLiteResponse {
  records: DoSearchAll[];
  total: number;
}
export interface ReleaseDoRequest {
  id: number;
}

export interface ReleaseDoResponse {
  id: number;
  entity: { status: string }
}


export interface AssignByStoreRequest {
  storeId: string; // "2/F" or "4/F"
  assignTo: number;
}

export interface AssignByStoreResponse {
  id: number;
  code: string;
  name: string;
  type: string;
  message: string;
  errorPosition: string;
  entity: any;
}

export interface PrintDeliveryNoteRequest{
  doPickOrderId: number;
  printerId: number;
  printQty: number;
  numOfCarton: number;
  isDraft: boolean;
}

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

export interface PrintDNLabelsRequest{
  doPickOrderId: number;
  printerId: number;
  printQty: number;
  numOfCarton: number;
}

export interface PrintDNLabelsReprintRequest{
  doPickOrderId: number;
  printerId: number;
  printQty: number;
  fromCarton: number;
  toCarton: number;
  totalCartonsOnShipment: number;
}

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

export interface BatchReleaseRequest {
  ids: number[];
}
export interface BatchReleaseResponse {
  success: boolean;
  message?: string
}

export interface getTicketReleaseTable {
  id: number;
  storeId: string | null;
  ticketNo: string | null;
  pickOrderId: number | null;
  doOrderId: number | null;
  pickOrderCode: string | null;
  deliveryOrderCode: string | null;
  loadingSequence: number | null;
  ticketStatus: string | null;
  truckId: number | null;
  truckDepartureTime: string | null;
  shopId: number | null;
  handledBy: number | null;
  ticketReleaseTime: string | null;
  ticketCompleteDateTime: string | null;
  truckLanceCode: string | null;
  shopCode: string | null;
  shopName: string | null;
  requiredDeliveryDate: string | null;
  handlerName: string | null;
  numberOfFGItems: number;
  /** 進行中 do_pick_order 為 true，才可呼叫 force-complete / revert-assignment（id 為 do_pick_order 主鍵） */
  isActiveDoPickOrder?: boolean;
}

export interface WorkbenchTicketReleaseTable {
  deliveryOrderPickOrderId: number;
  storeId: string | null;
  ticketNo: string | null;
  loadingSequence: number | null;
  ticketStatus: string | null;
  truckDepartureTime: string | null;
  handledBy: number | null;
  ticketReleaseTime: string | null;
  ticketCompleteDateTime: string | null;
  truckLanceCode: string | null;
  shopCode: string | null;
  shopName: string | null;
  requiredDeliveryDate: string | null;
  handlerName: string | null;
  numberOfFGItems: number;
  isActiveWorkbenchTicket?: boolean;
}

export interface WorkbenchTicketOpResponse {
  id: number | null;
  name: string | null;
  code: string;
  type: string | null;
  message: string | null;
  errorPosition: string | null;
  entity?: any;
}

export interface TruckScheduleDashboardItem {
  storeId: string | null;
  truckId: number | null;
  truckLanceCode: string | null;
  truckDepartureTime: string | number[] | null;
  numberOfShopsToServe: number;
  numberOfPickTickets: number;
  totalItemsToPick: number;
  numberOfTicketsReleased: number;
  firstTicketStartTime: string | number[] | null;
  numberOfTicketsCompleted: number;
  lastTicketEndTime: string | number[] | null;
  pickTimeTakenMinutes: number | null;
}
export interface SearchDeliveryOrderInfoRequest {
  code: string;
  shopName: string;
  status: string;
  orderStartDate: string;
  orderEndDate: string;
  estArrStartDate: string;
  estArrEndDate: string;
  pageSize: number;
  pageNum: number;
}
export interface SearchDeliveryOrderInfoResponse {
  records: DeliveryOrderInfo[];
  total: number;
}
export interface DeliveryOrderInfo {
  id: number;
  code: string;
  shopName: string;
  supplierName: string;  // 改为必需字段
  status: string;
  orderDate: string;
  
  estimatedArrivalDate: string;
  deliveryOrderLines: DoDetailLine[];
}
export const fetchDoRecordByPage = cache(async (data?: SearchDeliveryOrderInfoRequest) => {
  const queryStr = convertObjToURLSearchParams(data)
  console.log("queryStr", queryStr)
  const response = serverFetchJson<SearchDeliveryOrderInfoResponse>(
    `${BASE_API_URL}/jo/getRecordByPage?${queryStr}`,
    {
      method: "GET",
      headers: { "Content-Type": "application/json" },
      next: {
        tags: ["jos"]
      }
    }
  )

  return response
})
export const fetchTicketReleaseTable = cache(async (startDate: string, endDate: string)=> {
  return await serverFetchJson<getTicketReleaseTable[]>(
    `${BASE_API_URL}/doPickOrder/ticket-release-table/${startDate}&${endDate}`,
    {
      method: "GET",
    }
  );
});

export const fetchWorkbenchTicketReleaseTable = cache(async (startDate: string, endDate: string)=> {
  return await serverFetchJson<WorkbenchTicketReleaseTable[]>(
    `${BASE_API_URL}/doPickOrder/workbench/ticket-release-table/${startDate}&${endDate}`,
    {
      method: "GET",
    }
  );
});

export async function forceCompleteWorkbenchTicket(
  deliveryOrderPickOrderId: number,
): Promise<WorkbenchTicketOpResponse> {
  return await serverFetchJson<WorkbenchTicketOpResponse>(
    `${BASE_API_URL}/doPickOrder/workbench/force-complete/${deliveryOrderPickOrderId}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
    },
  );
}

export async function revertWorkbenchTicketAssignment(
  deliveryOrderPickOrderId: number,
): Promise<WorkbenchTicketOpResponse> {
  return await serverFetchJson<WorkbenchTicketOpResponse>(
    `${BASE_API_URL}/doPickOrder/workbench/revert-assignment/${deliveryOrderPickOrderId}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
    },
  );
}

export const fetchTruckScheduleDashboard = cache(async (date?: string) => {
  const url = date 
    ? `${BASE_API_URL}/doPickOrder/truck-schedule-dashboard?date=${date}`
    : `${BASE_API_URL}/doPickOrder/truck-schedule-dashboard`;
  return await serverFetchJson<TruckScheduleDashboardItem[]>(
    url,
    {
      method: "GET",
    }
  );
});
export const startBatchReleaseAsyncSingle = cache(async (data: { doId: number; userId: number }) => {
  const { doId, userId } = data;
  return await serverFetchJson<{ id: number|null; code: string; entity?: any }>(
    `${BASE_API_URL}/doPickOrder/batch-release/async-single?userId=${userId}`,
    {
      method: "POST",
      body: JSON.stringify(doId),
      headers: { "Content-Type": "application/json" },
    }
  );
});
export const startBatchReleaseAsync = cache(async (data: { ids: number[]; userId: number }) => {
  const { ids, userId } = data;
  return await serverFetchJson<{ id: number|null; code: string; entity?: any }>(
    `${BASE_API_URL}/doPickOrder/batch-release/async?userId=${userId}`,
    {
      method: "POST",
      body: JSON.stringify(ids),
      headers: { "Content-Type": "application/json" },
    }
  );
});

export const getBatchReleaseProgress = cache(async (jobId: string) => {
  return await serverFetchJson<{ id: number|null; code: string; entity?: any }>(
    `${BASE_API_URL}/doPickOrder/batch-release/progress/${jobId}`,
    { method: "GET" }
  );
});
export const assignPickOrderByStore = cache(async (data: AssignByStoreRequest) => {
  return await serverFetchJson<AssignByStoreResponse>(`${BASE_API_URL}/doPickOrder/assign-by-store`,
    {
      method: "POST",
      body: JSON.stringify(data),
      headers: { "Content-Type": "application/json" },
    })
})

export const releaseAssignedPickOrderByStore = cache(async (data: AssignByStoreRequest) => {
  return await serverFetchJson<AssignByStoreResponse>(`${BASE_API_URL}/doPickOrder/release-assigned-by-store`,
    {
      method: "POST",
      body: JSON.stringify(data),
      headers: { "Content-Type": "application/json" },
    })
})

export async function releaseDo(input: ReleaseDoRequest) {
  const response = await serverFetchJson<ReleaseDoResponse>(`${BASE_API_URL}/do/release`, {
      method: 'POST',
      body: JSON.stringify(input),
      headers: {
          'Content-Type': 'application/json',
      },
  });
  revalidateTag('do');
  return response;
}
export const preloadDo = () => {
  fetchDoList();
};

export const fetchDoList = cache(async () => {
  return serverFetchJson<DoResult[]>(`${BASE_API_URL}/do/list`, {
    next: { tags: ["doList"] },
  });
});

export const fetchDoDetail = cache(async (id: number) => {
  return serverFetchJson<DoDetail>(`${BASE_API_URL}/do/detail/${id}`, {
    method: "GET",
    headers: { "Content-Type": "application/json" },
    next: {
      tags: ["doDetail"]
    }
  });
});

export async function fetchDoSearch(
  code: string,
  shopName: string,
  status: string,
  orderStartDate: string,
  orderEndDate: string,
  estArrStartDate: string,
  estArrEndDate: string,
  pageNum?: number,
  pageSize?: number,
  truckLanceCode?: string,
  /** 後端：All/null 為全部；2F／4F 依供應商白名單篩選 */
  floor?: string | null,
  /** null：不篩；true／false：只顯示加單或非加單 DO */
  isExtra?: boolean | null,
): Promise<DoSearchLiteResponse> {
  // 构建请求体
  const requestBody: any = {
    code: code || null,
    shopName: shopName || null,
    status: status || null,
    estimatedArrivalDate: estArrStartDate || null, // 使用单个日期字段
    truckLanceCode: truckLanceCode || null,
    pageNum: pageNum || 1,
    pageSize: pageSize || 10,
    floor: floor && floor !== "All" ? floor : null,
    ...(isExtra !== undefined && isExtra !== null ? { isExtra } : {}),
  };

  // 如果日期不为空，转换为 LocalDateTime 格式
  if (estArrStartDate) {
    requestBody.estimatedArrivalDate = estArrStartDate; // 格式: "2026-01-19T00:00:00"
  } else {
    requestBody.estimatedArrivalDate = null;
  }

  /** v2：車線正規化、未指派合併、分批掃描（後端 /do/search-do-lite-v2） */
  const data = await serverFetchJson<DoSearchLiteResponse>(
    `${BASE_API_URL}/do/search-do-lite-v2`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(requestBody),
    },
  );

  return data;
}
export async function fetchDoSearchList(
  code: string,
  shopName: string,
  status: string,
  orderStartDate: string,
  orderEndDate: string,
  etaFrom: string,
  etaTo: string,
  page = 0,
  size = 500
): Promise<DoSearchAll[]> {
  const params = new URLSearchParams();

  if (code) params.append("code", code);
  if (shopName) params.append("shopName", shopName);
  if (status) params.append("status", status);
  if (orderStartDate) params.append("orderFrom", orderStartDate);
  if (orderEndDate) params.append("orderTo", orderEndDate);
  if (etaFrom) params.append("etaFrom", etaFrom);
  if (etaTo) params.append("etaTo", etaTo);

  params.append("page", String(page));
  params.append("size", String(size));

  const res = await fetch(`/api/delivery-order/search-do-list?${params.toString()}`);
  const pageData = await res.json(); // Spring Page 结构
  return pageData.content;           // 前端继续沿用你原来的 client-side 分页逻辑
}
export async function printDN(request: PrintDeliveryNoteRequest){
  const params = new URLSearchParams();
  params.append('doPickOrderId', request.doPickOrderId.toString()); 
  params.append('printerId', request.printerId.toString());
  if (request.printQty !== null && request.printQty !== undefined) {
    params.append('printQty', request.printQty.toString());
  }
  params.append('numOfCarton', request.numOfCarton.toString());
  params.append('isDraft', request.isDraft.toString());

  try {
    const response = await serverFetch(`${BASE_API_URL}/do/print-DN?${params.toString()}`, {
      method: "GET",
    });

    if (response.ok) {
      return { success: true, message: "Print job sent successfully (DN)" } as PrintDeliveryNoteResponse;
    }

    const errorText = await response.text();
    console.error("Print DN error:", errorText);
    return { 
      success: false, 
      message: "No data found for this pick order." 
    } as PrintDeliveryNoteResponse;

  } catch (error) {
    console.error("Error in printDN:", error);
    return { 
      success: false, 
      message: "No data found for this pick order." 
    } as PrintDeliveryNoteResponse;
  }
}

export async function printDNLabels(request: PrintDNLabelsRequest){
  const params = new URLSearchParams();
  params.append('doPickOrderId', request.doPickOrderId.toString());
  params.append('printerId', request.printerId.toString());
  if (request.printQty !== null && request.printQty !== undefined) {
    params.append('printQty', request.printQty.toString());
  }
  params.append('numOfCarton', request.numOfCarton.toString());

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

  return { success: true, message: "Print job sent successfully (labels)"} as PrintDeliveryNoteResponse
}

export async function printDNLabelsReprint(request: PrintDNLabelsReprintRequest){
  const params = new URLSearchParams();
  params.append('doPickOrderId', request.doPickOrderId.toString());
  params.append('printerId', request.printerId.toString());
  if (request.printQty !== null && request.printQty !== undefined) {
    params.append('printQty', request.printQty.toString());
  }
  params.append('fromCarton', request.fromCarton.toString());
  params.append('toCarton', request.toCarton.toString());
  params.append('totalCartonsOnShipment', request.totalCartonsOnShipment.toString());

  await serverFetchWithNoContent(`${BASE_API_URL}/do/print-DNLabels-reprint?${params.toString()}`,{
    method: "GET"
  });

  return { success: true, message: "Print job sent successfully (reprint labels)"} as PrintDeliveryNoteResponse
}

export interface PrintWorkbenchDeliveryNoteRequest{
  deliveryOrderPickOrderId: number;
  printerId: number;
  printQty: number;
  numOfCarton: number;
  isDraft: boolean;
}

export interface PrintWorkbenchDNLabelsRequest{
  deliveryOrderPickOrderId: number;
  printerId: number;
  printQty: number;
  numOfCarton: number;
}
export interface PrintWorkbenchDNLabelsReprintRequest{
  deliveryOrderPickOrderId: number;
  printerId: number;
  printQty: number;
  fromCarton: number;
  toCarton: number;
  totalCartonsOnShipment: number;
}
export async function printDNWorkbench(request: PrintWorkbenchDeliveryNoteRequest){
  const params = new URLSearchParams();
  params.append("doPickOrderId", request.deliveryOrderPickOrderId.toString());
  params.append("printerId", request.printerId.toString());
  if (request.printQty !== null && request.printQty !== undefined) {
    params.append("printQty", request.printQty.toString());
  }
  params.append("numOfCarton", request.numOfCarton.toString());
  params.append("isDraft", request.isDraft.toString());

  try {
    const response = await serverFetch(`${BASE_API_URL}/doPickOrder/workbench/print-DN?${params.toString()}`, {
      method: "GET",
    });
    if (response.ok) {
      return { success: true, message: "Print job sent successfully (workbench DN)" } as PrintDeliveryNoteResponse;
    }
    const errorText = await response.text();
    console.error("Workbench print DN error:", errorText);
    return {
      success: false,
      message: "No workbench data found for this ticket.",
    } as PrintDeliveryNoteResponse;
  } catch (error) {
    console.error("Error in printDNWorkbench:", error);
    return {
      success: false,
      message: "No workbench data found for this ticket.",
    } as PrintDeliveryNoteResponse;
  }
}

export async function printDNLabelsWorkbench(request: PrintWorkbenchDNLabelsRequest){
  const params = new URLSearchParams();
  params.append("doPickOrderId", request.deliveryOrderPickOrderId.toString());
  params.append("printerId", request.printerId.toString());
  if (request.printQty !== null && request.printQty !== undefined) {
    params.append("printQty", request.printQty.toString());
  }
  params.append("numOfCarton", request.numOfCarton.toString());

  await serverFetchWithNoContent(`${BASE_API_URL}/doPickOrder/workbench/print-DNLabels?${params.toString()}`,{
    method: "GET"
  });

  return { success: true, message: "Print job sent successfully (workbench labels)"} as PrintDeliveryNoteResponse
}

export async function printDNLabelsReprintWorkbench(request: PrintWorkbenchDNLabelsReprintRequest){
  const params = new URLSearchParams();
  params.append("doPickOrderId", request.deliveryOrderPickOrderId.toString());
  params.append("printerId", request.printerId.toString());
  if (request.printQty !== null && request.printQty !== undefined) {
    params.append("printQty", request.printQty.toString());
  }
  params.append("fromCarton", request.fromCarton.toString());
  params.append("toCarton", request.toCarton.toString());
  params.append("totalCartonsOnShipment", request.totalCartonsOnShipment.toString());

  await serverFetchWithNoContent(`${BASE_API_URL}/doPickOrder/workbench/print-DNLabels-reprint?${params.toString()}`,{
    method: "GET"
  });

  return { success: true, message: "Print job sent successfully (workbench reprint labels)"} as PrintDeliveryNoteResponse
}

export interface Check4FTruckBatchResponse {
  hasProblem: boolean;
  problems: ProblemDoDto[];
}
export interface ProblemDoDto {
  deliveryOrderId: number;
  deliveryOrderCode: string;
  targetDate: string;
  availableTrucks: TruckInfoDto[];
}
export interface TruckInfoDto {
  id: number;
  truckLanceCode: string;
  departureTime: string;
  storeId: string;
  shopCode: string;
  shopName: string;
}
export const check4FTrucksBatch = cache(async (doIds: number[]) => {
  return await serverFetchJson<Check4FTruckBatchResponse>(`${BASE_API_URL}/do/check-4f-trucks-batch`, {
    method: "POST",
    body: JSON.stringify(doIds),
    headers: { "Content-Type": "application/json" },
  });
});

export async function fetchAllDoSearch(
  code: string,
  shopName: string,
  status: string,
  estArrStartDate: string,
  truckLanceCode?: string,
  floor?: string | null,
  isExtra?: boolean | null,
): Promise<DoSearchAll[]> {
  // 使用一个很大的 pageSize 来获取所有匹配的记录
  const requestBody: any = {
    code: code || null,
    shopName: shopName || null,
    status: status || null,
    estimatedArrivalDate: estArrStartDate || null,
    truckLanceCode: truckLanceCode || null,
    pageNum: 1,
    pageSize: 10000, // 使用一个很大的值来获取所有记录
    floor: floor && floor !== "All" ? floor : null,
    ...(isExtra !== undefined && isExtra !== null ? { isExtra } : {}),
  };

  if (estArrStartDate) {
    requestBody.estimatedArrivalDate = estArrStartDate;
  } else {
    requestBody.estimatedArrivalDate = null;
  }

  const data = await serverFetchJson<DoSearchLiteResponse>(
    `${BASE_API_URL}/do/search-do-lite-v2`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(requestBody),
    },
  );

  return data.records;
}
