import dayjs from "dayjs";
import {
  ItemLotTraceJoPrelude,
  ItemLotTraceResponse,
} from "@/app/api/itemTracing";

export const isWorkbenchTicketNo = (ticketNo?: string | null): boolean =>
  (ticketNo ?? "").trim().toUpperCase().startsWith("TI-");

/** Normalize any date/datetime string to YYYY-MM-DD for API / URL query params (LocalDate). */
export const normalizeTargetDateForLink = (
  value?: string | null,
): string | undefined => {
  if (value == null) return undefined;
  const raw = String(value).trim();
  if (!raw) return undefined;
  // Prefer extracting YYYY-MM-DD prefix — dayjs/Date.parse is unreliable for
  // "YYYY-MM-DD HH:mm:ss" in some browsers (e.g. Safari).
  const match = raw.match(/(\d{4}-\d{2}-\d{2})/);
  if (match) return match[1];
  const d = dayjs(raw);
  return d.isValid() ? d.format("YYYY-MM-DD") : undefined;
};

export const targetDateFromTraceTimestamp = (
  timestamp?: string | null,
): string | undefined => normalizeTargetDateForLink(timestamp);

export type DoOutboundDocLink = {
  kind: "workbench" | "pick" | undefined;
  ticketNo?: string;
  targetDate?: string;
  /** Visible link label (DO code preferred on DO_OUT cards). */
  displayCode: string;
  pickOrderId?: number | null;
  consoCode?: string;
};

export type JoPickDocLink = {
  kind: "jodetail";
  pickOrderCode: string;
  targetDate?: string;
  displayCode: string;
  pickOrderId?: number | null;
};

const walkJoPreludePickOrders = (
  prelude: ItemLotTraceJoPrelude,
  map: Map<string, string>,
): void => {
  prelude.pickOrders.forEach((po) => {
    const code = po.pickOrderCode?.trim();
    const date = normalizeTargetDateForLink(po.targetDate);
    if (code && date) map.set(code, date);
  });
  prelude.materialInputs.forEach((m) => {
    if (m.nestedJoPrelude) walkJoPreludePickOrders(m.nestedJoPrelude, map);
  });
};

export const buildPickOrderTargetDateMapFromPrelude = (
  prelude: ItemLotTraceJoPrelude,
): Map<string, string> => {
  const map = new Map<string, string>();
  walkJoPreludePickOrders(prelude, map);
  return map;
};

export const buildPickOrderTargetDateMap = (
  data: ItemLotTraceResponse,
): Map<string, string> =>
  data.joPrelude ? buildPickOrderTargetDateMapFromPrelude(data.joPrelude) : new Map();

export const resolvePickOrderTargetDate = (
  map: Map<string, string>,
  pickOrderCode?: string | null,
  fallbackTimestamp?: string | null,
): string | undefined => {
  const code = pickOrderCode?.trim();
  if (code) {
    const fromPrelude = normalizeTargetDateForLink(map.get(code));
    if (fromPrelude) return fromPrelude;
  }
  return targetDateFromTraceTimestamp(fallbackTimestamp);
};

export const resolveJoPickDocLink = (input: {
  pickOrderCode?: string;
  pickOrderId?: number | null;
  timestamp?: string | null;
  targetDate?: string | null;
}): JoPickDocLink | null => {
  const pickCode = input.pickOrderCode?.trim() || "";
  if (!pickCode) return null;
  return {
    kind: "jodetail",
    pickOrderCode: pickCode,
    targetDate:
      normalizeTargetDateForLink(input.targetDate) ||
      targetDateFromTraceTimestamp(input.timestamp),
    displayCode: pickCode,
    pickOrderId: input.pickOrderId,
  };
};

export const resolveDoOutboundDocLink = (input: {
  pickOrderCode?: string;
  pickOrderId?: number | null;
  deliveryOrderCode?: string;
  ticketNo?: string;
  outboundTicketNo?: string;
  consoCode?: string;
  timestamp?: string | null;
  /** Workbench path only when linked to delivery_order_pick_order. */
  deliveryOrderPickOrderId?: number | null;
}): DoOutboundDocLink => {
  const ticket = (input.ticketNo || input.outboundTicketNo || "").trim();
  const conso = (input.consoCode || "").trim();
  const hasWorkbenchLink =
    input.deliveryOrderPickOrderId != null &&
    Number.isFinite(Number(input.deliveryOrderPickOrderId));
  const workbenchTicket = hasWorkbenchLink
    ? isWorkbenchTicketNo(ticket)
      ? ticket
      : isWorkbenchTicketNo(conso)
        ? conso
        : undefined
    : undefined;
  const targetDate = targetDateFromTraceTimestamp(input.timestamp);
  const pickCode = input.pickOrderCode?.trim() || "";
  const doCode = input.deliveryOrderCode?.trim() || "";

  if (workbenchTicket) {
    return {
      kind: "workbench",
      ticketNo: workbenchTicket,
      targetDate,
      displayCode: doCode || pickCode || workbenchTicket,
      pickOrderId: input.pickOrderId,
      consoCode: conso || pickCode,
    };
  }
  // Prefer 送貨單號 on the card; /pickOrder/detail is retired so no pick-only link.
  // Legacy GoodPick TI-* without deliveryOrderPickOrderId must not deep-link to workbench.
  if (doCode || pickCode) {
    return {
      kind: undefined,
      displayCode: doCode || pickCode,
      pickOrderId: input.pickOrderId,
      consoCode: conso || pickCode,
      targetDate,
    };
  }
  return { kind: undefined, displayCode: "—" };
};
