import type { DoSearchAll } from "@/app/api/do/actions";
import type { DoReplenishmentRecord } from "@/app/api/do/replenishmentTypes";
import { NAVIGATION_CONTENT_WIDTH } from "@/config/uiConfig";
import { TFunction } from "i18next";

function normalizeText(value: string | null | undefined): string {
  return (value ?? "").trim().toLowerCase();
}

function shopTokenFromDoRow(doRow: DoSearchAll): string {
  const raw = doRow.shopName?.trim() ?? "";
  if (!raw) return "";
  return normalizeText(raw.split(" - ")[0] || raw);
}

/** Replenishment must match the same shop + truck lane as a DO in this batch release. */
export function replenishmentMatchesDoRow(
  record: DoReplenishmentRecord,
  doRow: DoSearchAll,
): boolean {
  const doTruck = normalizeText(doRow.truckLanceCode);
  const recordTruck = normalizeText(record.truckLaneCode);
  if (doTruck) {
    if (!recordTruck || recordTruck !== doTruck) return false;
  }

  const doShopToken = shopTokenFromDoRow(doRow);
  if (!doShopToken) return false;

  const recordShopCode = normalizeText(record.shopCode);
  const recordShopName = normalizeText(record.shopName);
  return (
    recordShopCode === doShopToken ||
    recordShopName.startsWith(doShopToken) ||
    (recordShopCode.length > 0 && doShopToken.startsWith(recordShopCode)) ||
    (recordShopCode.length > 0 && recordShopCode.startsWith(doShopToken))
  );
}

export function filterReplenishmentsForBatchDos(
  records: DoReplenishmentRecord[],
  dosForRelease: DoSearchAll[],
): DoReplenishmentRecord[] {
  if (dosForRelease.length === 0) return [];
  return records.filter((record) =>
    dosForRelease.some((doRow) => replenishmentMatchesDoRow(record, doRow)),
  );
}

/** Narrow API query from selected DOs when search box shop/truck is empty. */
export function deriveReplenishmentFetchParams(
  dosForRelease: DoSearchAll[],
  searchShopName: string,
  searchTruckLaneCode: string,
): { shopName?: string; truckLaneCode?: string } {
  const shopFromSearch = searchShopName.trim();
  const truckFromSearch = searchTruckLaneCode.trim();
  if (shopFromSearch || truckFromSearch) {
    return {
      shopName: shopFromSearch || undefined,
      truckLaneCode: truckFromSearch || undefined,
    };
  }

  const shopTokens = Array.from(
    new Set(dosForRelease.map(shopTokenFromDoRow).filter(Boolean)),
  );
  const trucks = Array.from(
    new Set(
      dosForRelease
        .map((row) => row.truckLanceCode?.trim())
        .filter((value): value is string => Boolean(value)),
    ),
  );

  if (shopTokens.length === 1 && trucks.length === 1) {
    return { shopName: shopTokens[0], truckLaneCode: trucks[0] };
  }
  if (shopTokens.length === 1) {
    return { shopName: shopTokens[0] };
  }
  if (trucks.length === 1) {
    return { truckLaneCode: trucks[0] };
  }
  return {};
}

const BATCH_RELEASE_SWAL_SCROLL_CLASS = "do-batch-release-replenish-scroll";

/** Matches MUI `xl` — permanent nav drawer visible at this width and above. */
export const MUI_XL_BREAKPOINT_PX = 1440;

/** Keep full-viewport backdrop; shift popup so it centers over `<main>`, not the sidebar. */
export function applyMainContentAreaSwalOffset(popup: HTMLElement): void {
  const container = popup.closest(".swal2-container");
  if (container instanceof HTMLElement) {
    container.style.marginLeft = "";
    container.style.width = "";
  }

  if (!window.matchMedia(`(min-width: ${MUI_XL_BREAKPOINT_PX}px)`).matches) {
    popup.style.marginLeft = "";
    return;
  }

  popup.style.marginLeft = `calc(${NAVIGATION_CONTENT_WIDTH} / 2)`;
}

function applyCompactSwalIcon(popup: HTMLElement): void {
  const icon = popup.querySelector(".swal2-icon");
  if (icon instanceof HTMLElement) {
    icon.style.width = "2.5em";
    icon.style.height = "2.5em";
    icon.style.margin = "0.35em auto 0.25em";
    icon.style.fontSize = "0.75em";
  }
}

/** ~110% of prior 920px so 100% browser zoom matches previous balance. */
export const BATCH_RELEASE_SWAL_WIDTH_WITH_REPLENISH = 1024;

function escapeHtml(text: string): string {
  return text
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;");
}

function shopKey(record: DoReplenishmentRecord): string {
  return (record.shopCode ?? record.shopName ?? "").trim().toLowerCase();
}

function shouldShowShopColumn(records: DoReplenishmentRecord[]): boolean {
  const keys = new Set(records.map(shopKey).filter(Boolean));
  return keys.size > 1;
}

export function buildBatchReleaseReplenishmentHtml(
  records: DoReplenishmentRecord[],
  t: TFunction,
): string {
  if (records.length === 0) {
    return `<p style="font-size:0.9em;color:#666;margin-top:16px;">${escapeHtml(
      t("Batch release no pending replenishment"),
    )}</p>`;
  }

  const showShopColumn = shouldShowShopColumn(records);
  const thStyle =
    "padding:7px 10px;text-align:left;font-weight:600;border-bottom:1px solid #ddd;white-space:nowrap;font-size:13px;";
  const tdBase =
    "padding:7px 10px;text-align:left;vertical-align:top;border-top:1px solid #eee;font-size:13px;line-height:1.35;";

  const headers: string[] = [t("Replenishment Code")];
  if (showShopColumn) headers.push(t("Shop Name"));
  headers.push(t("Item No."), t("Item Name"), t("Replenish Qty"), t("Source DO"));

  const headerCells = headers
    .map((label) => `<th style="${thStyle}">${escapeHtml(label)}</th>`)
    .join("");

  const colgroup = showShopColumn
    ? `<colgroup>
        <col style="width:128px" />
        <col style="width:148px" />
        <col style="width:76px" />
        <col />
        <col style="width:72px" />
        <col style="width:148px" />
      </colgroup>`
    : `<colgroup>
        <col style="width:132px" />
        <col style="width:80px" />
        <col />
        <col style="width:76px" />
        <col style="width:152px" />
      </colgroup>`;

  const bodyRows = records
    .map((row) => {
      const qtyLabel = row.shortUom
        ? `${row.replenishQty} ${row.shortUom}`
        : String(row.replenishQty);
      const shopLabel = row.shopName ?? row.shopCode ?? "—";
      const itemName = row.itemName ?? "—";
      const shopCell = showShopColumn
        ? `<td style="${tdBase}word-break:break-word;" title="${escapeHtml(shopLabel)}">${escapeHtml(shopLabel)}</td>`
        : "";
      return `<tr>
        <td style="${tdBase}white-space:nowrap;">${escapeHtml(row.code)}</td>
        ${shopCell}
        <td style="${tdBase}white-space:nowrap;">${escapeHtml(row.itemNo ?? "—")}</td>
        <td style="${tdBase}word-break:break-word;" title="${escapeHtml(itemName)}">${escapeHtml(itemName)}</td>
        <td style="${tdBase}white-space:nowrap;">${escapeHtml(qtyLabel)}</td>
        <td style="${tdBase}white-space:nowrap;">${escapeHtml(row.sourceDoCode ?? "—")}</td>
      </tr>`;
    })
    .join("");

  const scrollMaxHeight = records.length <= 4 ? "none" : "200px";

  return `
    <div class="do-batch-release-replenish-section" style="margin-top:12px;text-align:left;width:100%;box-sizing:border-box;">
      <p style="font-weight:600;margin:0 0 6px;text-align:left;font-size:14px;">${escapeHtml(
        t("Batch release pending replenishment", { count: records.length }),
      )}</p>
      <p style="font-size:13px;color:#666;margin:0 0 8px;text-align:left;">${escapeHtml(
        t("Batch release replenishment info only"),
      )}</p>
      <div class="${BATCH_RELEASE_SWAL_SCROLL_CLASS}" style="max-height:${scrollMaxHeight};overflow:${scrollMaxHeight === "none" ? "visible" : "auto"};border:1px solid #ddd;border-radius:4px;width:100%;box-sizing:border-box;">
        <table style="width:100%;table-layout:fixed;border-collapse:collapse;">
          ${colgroup}
          <thead>
            <tr style="background:#f5f5f5;">${headerCells}</tr>
          </thead>
          <tbody>${bodyRows}</tbody>
        </table>
      </div>
    </div>
  `;
}

/** SweetAlert2 centers html-container by default; fix layout for left-aligned table. */
export function applyBatchReleaseSwalLayout(
  popup: HTMLElement,
  options?: { wide?: boolean },
): void {
  applyMainContentAreaSwalOffset(popup);
  applyCompactSwalIcon(popup);

  const wide = options?.wide ?? false;
  if (!wide) {
    return;
  }

  popup.style.width = `${BATCH_RELEASE_SWAL_WIDTH_WITH_REPLENISH}px`;
  popup.style.maxWidth = `calc(100vw - ${NAVIGATION_CONTENT_WIDTH} - 48px)`;
  popup.style.boxSizing = "border-box";
  popup.style.padding = "1.1em 1.35em 1.25em";

  const title = popup.querySelector(".swal2-title");
  if (title instanceof HTMLElement) {
    title.style.padding = "0.4em 0 0";
    title.style.fontSize = "1.35em";
  }

  const htmlContainer = popup.querySelector(".swal2-html-container");
  if (htmlContainer instanceof HTMLElement) {
    htmlContainer.style.textAlign = "left";
    htmlContainer.style.overflow = "visible";
    htmlContainer.style.maxHeight = "none";
    htmlContainer.style.margin = "0.25em 0 0";
    htmlContainer.style.padding = "0";
    htmlContainer.style.width = "100%";
    htmlContainer.style.boxSizing = "border-box";
  }

  popup.querySelectorAll(".do-batch-release-swal-body, .do-batch-release-replenish-section").forEach((el) => {
    if (el instanceof HTMLElement) {
      el.style.width = "100%";
      el.style.boxSizing = "border-box";
    }
  });

  const scrollBox = popup.querySelector(`.${BATCH_RELEASE_SWAL_SCROLL_CLASS}`);
  if (scrollBox instanceof HTMLElement) {
    scrollBox.style.display = "block";
    scrollBox.style.width = "100%";
    scrollBox.style.boxSizing = "border-box";
  }

  const actions = popup.querySelector(".swal2-actions");
  if (actions instanceof HTMLElement) {
    actions.style.marginTop = "0.85em";
  }
}
