"use client";

import { NEXT_PUBLIC_API_URL } from "@/config/api";
import { clientAuthFetch } from "@/app/utils/clientAuthFetch";

export interface JobOrderListItem {
  id: number;
  code: string | null;
  planStart: string | null;
  itemCode: string | null;
  itemName: string | null;
  reqQty: number | null;
  stockInLineId: number | null;
  itemId: number | null;
  lotNo: string | null;
  /** 打袋機 DataFlex cumulative printed qty */
  bagPrintedQty?: number;
  /** 標簽機 cumulative printed qty */
  labelPrintedQty?: number;
  /** 激光機 cumulative printed qty */
  laserPrintedQty?: number;
}

export interface PrinterStatusRequest {
  printerType: "dataflex" | "laser";
  printerIp?: string;
  printerPort?: number;
}

export interface PrinterStatusResponse {
  connected: boolean;
  message: string;
}

export interface OnPackQrDownloadRequest {
  jobOrders: {
    jobOrderId: number;
    itemCode: string;
  }[];
}

/** Same mapping as Bag Print download buttons: one entry per row with a non-empty item code. */
export function buildOnPackJobOrdersPayload(jobOrders: JobOrderListItem[]): {
  jobOrderId: number;
  itemCode: string;
}[] {
  return jobOrders
    .map((jobOrder) => ({
      jobOrderId: jobOrder.id,
      itemCode: jobOrder.itemCode?.trim() || "",
    }))
    .filter((jobOrder) => jobOrder.itemCode.length > 0);
}

export interface NgpclPushResponse {
  pushed: boolean;
  message: string;
}

/**
 * POST the same lemon OnPack ZIP bytes as download-onpack-qr-text to the server-configured NGPCL HTTP endpoint (ngpcl.push-url).
 * When the URL is not configured, response has pushed=false — use download ZIP instead.
 */
export async function pushOnPackTextQrZipToNgpcl(request: OnPackQrDownloadRequest): Promise<NgpclPushResponse> {
  const url = `${NEXT_PUBLIC_API_URL}/plastic/ngpcl/push-onpack-qr-text`;
  const res = await clientAuthFetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(request),
  });
  if (res.status === 401 || res.status === 403) {
    return { pushed: false, message: "Session expired or unauthorized." };
  }
  const data = (await res.json()) as NgpclPushResponse;
  if (!res.ok) {
    throw new Error(data.message || `HTTP ${res.status}`);
  }
  return data;
}

/** Readable message when ZIP download returns non-OK (plain text, JSON error body, or generic). */
async function zipDownloadError(res: Response): Promise<Error> {
  const text = await res.text();
  const ct = res.headers.get("content-type") ?? "";
  if (ct.includes("application/json")) {
    try {
      const j = JSON.parse(text) as { message?: string; error?: string };
      if (typeof j.message === "string" && j.message.length > 0) {
        return new Error(j.message);
      }
      if (typeof j.error === "string" && j.error.length > 0) {
        return new Error(j.error);
      }
    } catch {
      /* ignore parse */
    }
  }
  if (text && text.length > 0 && text.length < 800 && !text.trim().startsWith("{")) {
    return new Error(text);
  }
  return new Error(`下載失敗（HTTP ${res.status}）。請查看後端日誌或確認資料庫已執行 Liquibase 更新。`);
}

/**
 * Fetch job orders by plan date from GET /py/job-orders.
 * Client-side only; uses auth token from localStorage.
 */
export async function fetchJobOrders(planStart: string): Promise<JobOrderListItem[]> {
  const url = `${NEXT_PUBLIC_API_URL}/py/job-orders?planStart=${encodeURIComponent(planStart)}`;
  const res = await clientAuthFetch(url, { method: "GET" });
  if (!res.ok) {
    throw new Error(`Failed to fetch job orders: ${res.status}`);
  }
  return res.json();
}

export async function checkPrinterStatus(
  request: PrinterStatusRequest,
): Promise<PrinterStatusResponse> {
  const url = `${NEXT_PUBLIC_API_URL}/plastic/check-printer`;
  const res = await clientAuthFetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(request),
  });

  const data = (await res.json()) as PrinterStatusResponse;
  if (!res.ok) {
    return data;
  }

  return data;
}

export async function downloadOnPackQrZip(
  request: OnPackQrDownloadRequest,
): Promise<Blob> {
  const url = `${NEXT_PUBLIC_API_URL}/plastic/download-onpack-qr`;
  const res = await clientAuthFetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(request),
  });

  if (!res.ok) {
    throw await zipDownloadError(res);
  }

  return res.blob();
}

/** OnPack2023 檸檬機 — text QR template (`onpack2030_2`), no separate .bmp */
export async function downloadOnPackTextQrZip(
  request: OnPackQrDownloadRequest,
): Promise<Blob> {
  const url = `${NEXT_PUBLIC_API_URL}/plastic/download-onpack-qr-text`;
  const res = await clientAuthFetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(request),
  });

  if (!res.ok) {
    throw await zipDownloadError(res);
  }

  return res.blob();
}
