"use client";

import React, { useState, useEffect, useCallback, useRef, useMemo } from "react";
import { useRouter } from "next/navigation";
import { apiClient } from "@/lib/api/client";
import { InspectionModal, type InspectionResult } from "../inbound/InspectionModal";
import { NumberPadModal, type PackageEntry } from "../inbound/NumberPadModal";
import { useCartSync, type CartItemWithId } from "../common/useCartSync";

/* ------------------------------------------------------------------ */
/* Types                                                               */
/* ------------------------------------------------------------------ */

interface Warehouse {
  warehouse_code: string;
  warehouse_name: string;
  warehouse_type?: string;
}

/** CartItemWithId -> display parsed result */
interface CartItemParsed {
  id: string;
  rowKey: string;
  dbId: string;
  source_table: string;
  source_id: string;
  instruction_no: string;
  item_code: string;
  item_name: string;
  spec: string;
  material: string;
  plan_qty: number;
  remain_qty: number;
  outbound_qty: number;
  unit_price: number;
  customer_code: string;
  customer_name: string;
  instruction_date?: string;
  inspection_required?: boolean;
  inspection_type?: "self" | "request" | null;
  packages?: PackageEntry[];
  image?: string | null;
}

/* ------------------------------------------------------------------ */
/* Helper: CartItemWithId -> CartItemParsed                            */
/* ------------------------------------------------------------------ */
function toCartItemParsed(item: CartItemWithId): CartItemParsed {
  const data = item.row;
  const inspType = data.inspection_type === "self" ? "self"
    : data.inspection_type === "request" ? "request"
    : null;

  return {
    id: item.rowKey || String(data.id ?? ""),
    rowKey: item.rowKey,
    dbId: item.cartId || "",
    source_table: item.sourceTable || String(data.source_table ?? "shipment_instruction_detail"),
    source_id: item.rowKey || String(data.source_id ?? data.detail_id ?? data.id ?? ""),
    instruction_no: String(data.instruction_no ?? ""),
    item_code: String(data.item_code ?? ""),
    item_name: String(data.item_name ?? ""),
    spec: String(data.spec ?? ""),
    material: String(data.material ?? ""),
    plan_qty: Number(data.plan_qty ?? 0),
    remain_qty: Number(data.remain_qty ?? 0),
    outbound_qty: item.quantity,
    unit_price: Number(data.unit_price ?? 0),
    customer_code: String(data.customer_code ?? ""),
    customer_name: String(data.customer_name ?? ""),
    instruction_date: data.instruction_date ? String(data.instruction_date) : undefined,
    inspection_type: inspType,
    inspection_required: inspType === "self",
    packages: item.packageEntries as unknown as PackageEntry[] | undefined,
    image: data.image ? String(data.image) : null,
  };
}

/* ------------------------------------------------------------------ */
/* Component                                                           */
/* ------------------------------------------------------------------ */

export function OutboundCartPage() {
  const router = useRouter();

  /* Cart sync hook */
  const cart = useCartSync("pop-sales-outbound", "shipment_instruction_detail");

  /* Derived: parsed items from cart */
  const items = useMemo(
    () => cart.cartItems.map(toCartItemParsed),
    [cart.cartItems],
  );

  /* Inspection results (local overlay, keyed by rowKey) */
  const [inspectionResults, setInspectionResults] = useState<
    Map<string, InspectionResult>
  >(new Map());

  /* Selection */
  const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());

  /* Auto-select all when items change */
  useEffect(() => {
    if (items.length > 0) {
      setSelectedItems(new Set(items.map((i) => i.id)));
    }
  }, [items]);

  /* Warehouse */
  const [warehouses, setWarehouses] = useState<Warehouse[]>([]);
  const [selectedWarehouse, setSelectedWarehouse] = useState<string>("");
  const [warehousePickerOpen, setWarehousePickerOpen] = useState(false);

  /* Outbound number */
  const [outboundNumber, setOutboundNumber] = useState<string>("");

  /* Confirm result modal */
  const [confirmResult, setConfirmResult] = useState<{
    outboundNumber: string;
    items: CartItemParsed[];
    warehouse: string;
    date: string;
  } | null>(null);

  /* Outbound date */
  const [outboundDate, setOutboundDate] = useState<string>(
    new Date().toISOString().slice(0, 10)
  );

  /* Confirm state */
  const [confirming, setConfirming] = useState(false);
  const [resultMsg, setResultMsg] = useState<string | null>(null);

  /* Inspection modal */
  const [inspectionModalOpen, setInspectionModalOpen] = useState(false);
  const [inspectionTarget, setInspectionTarget] = useState<CartItemParsed | null>(null);

  /* Numpad modal (for qty edit) */
  const [numpadOpen, setNumpadOpen] = useState(false);
  const [numpadTarget, setNumpadTarget] = useState<CartItemParsed | null>(null);

  /* Derived: customer name (all items should be same customer) */
  const customerName = items.length > 0 ? items[0].customer_name : "";

  /* ------------------------------------------------------------------ */
  /* Fetch warehouses                                                    */
  /* ------------------------------------------------------------------ */
  const fetchedRef = useRef(false);

  const fetchWarehouses = useCallback(async () => {
    try {
      const res = await apiClient.get("/outbound/warehouses");
      const data: Warehouse[] = res.data?.data ?? [];
      setWarehouses(data);
      if (data.length > 0) {
        setSelectedWarehouse(data[0].warehouse_code);
      }
    } catch {
      /* keep empty */
    }
  }, []);

  useEffect(() => {
    if (fetchedRef.current) return;
    fetchedRef.current = true;
    fetchWarehouses();
  }, [fetchWarehouses]);

  /* ------------------------------------------------------------------ */
  /* Selection                                                           */
  /* ------------------------------------------------------------------ */
  const toggleSelect = (id: string) => {
    setSelectedItems((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const toggleSelectAll = () => {
    if (selectedItems.size === items.length) {
      setSelectedItems(new Set());
    } else {
      setSelectedItems(new Set(items.map((i) => i.id)));
    }
  };

  /* ------------------------------------------------------------------ */
  /* Qty edit via numpad                                                  */
  /* ------------------------------------------------------------------ */
  const openNumpad = (item: CartItemParsed) => {
    setNumpadTarget(item);
    setNumpadOpen(true);
  };

  const handleNumpadConfirm = (qty: number, packages: PackageEntry[]) => {
    if (!numpadTarget) return;
    const finalQty = Math.min(qty, numpadTarget.remain_qty);

    cart.updateItemQuantity(
      numpadTarget.rowKey,
      finalQty,
      undefined,
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      packages.length > 0 ? packages as any : undefined,
    );
    setNumpadTarget(null);
  };

  /* ------------------------------------------------------------------ */
  /* Remove item                                                         */
  /* ------------------------------------------------------------------ */
  const handleRemove = (rowKey: string) => {
    cart.removeItem(rowKey);
    setSelectedItems((prev) => {
      const next = new Set(prev);
      next.delete(rowKey);
      return next;
    });
  };

  /* Auto-save: persist dirty changes to DB after a short debounce */
  const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  useEffect(() => {
    if (!cart.isDirty || cart.syncStatus === "saving") return;
    if (autoSaveTimerRef.current) clearTimeout(autoSaveTimerRef.current);
    autoSaveTimerRef.current = setTimeout(() => {
      cart.saveToDb().catch(() => {});
    }, 500);
    return () => {
      if (autoSaveTimerRef.current) clearTimeout(autoSaveTimerRef.current);
    };
  }, [cart.isDirty, cart.syncStatus, cart]);

  /* ------------------------------------------------------------------ */
  /* Inspection                                                          */
  /* ------------------------------------------------------------------ */
  const openInspection = (item: CartItemParsed) => {
    setInspectionTarget(item);
    setInspectionModalOpen(true);
  };

  const handleInspectionComplete = (result: InspectionResult) => {
    if (!inspectionTarget) return;
    setInspectionResults((prev) => {
      const next = new Map(prev);
      next.set(inspectionTarget.rowKey, result);
      return next;
    });
    setInspectionTarget(null);
  };

  const handlePassInspection = (rowKey: string) => {
    const item = items.find((i) => i.rowKey === rowKey);
    if (!item) return;
    setInspectionResults((prev) => {
      const next = new Map(prev);
      next.set(rowKey, {
        items: [],
        goodQty: item.outbound_qty,
        badQty: 0,
        remark: "pass",
        completed: true,
      });
      return next;
    });
  };

  const getInspectionResult = (rowKey: string): InspectionResult | null => {
    return inspectionResults.get(rowKey) || null;
  };

  /* ------------------------------------------------------------------ */
  /* Validation: required inspections                                    */
  /* ------------------------------------------------------------------ */
  const selectedItemsList = items.filter((i) => selectedItems.has(i.id));

  const hasUnfinishedRequiredInspection = selectedItemsList.some(
    (item) =>
      item.inspection_required &&
      item.inspection_type === "self" &&
      !getInspectionResult(item.rowKey)?.completed
  );

  /* ------------------------------------------------------------------ */
  /* Confirm outbound                                                    */
  /* ------------------------------------------------------------------ */
  const handleConfirm = async () => {
    if (selectedItemsList.length === 0) return;

    if (!selectedWarehouse) {
      setResultMsg("오류: 출고 창고를 선택해주세요.");
      return;
    }

    if (hasUnfinishedRequiredInspection) {
      setResultMsg("오류: 필수 검사를 완료해주세요.");
      return;
    }

    setConfirming(true);
    setResultMsg(null);

    try {
      // Generate outbound number at confirm time
      let finalNumber = "";
      try {
        const numRes = await apiClient.get("/outbound/generate-number");
        if (numRes.data?.success && numRes.data?.data) {
          finalNumber = numRes.data.data;
          setOutboundNumber(finalNumber);
        }
      } catch {
        /* backend will handle */
      }

      // POST /api/outbound -- matches outboundController.create
      const payload = {
        outbound_number: finalNumber,
        outbound_date: outboundDate,
        warehouse_code: selectedWarehouse,
        items: selectedItemsList.map((item) => ({
          outbound_type: "판매출고",
          item_code: item.item_code,
          item_name: item.item_name,
          specification: item.spec || "",
          spec: item.spec || "",
          material: item.material || "",
          unit: "EA",
          outbound_qty: item.outbound_qty,
          unit_price: item.unit_price || 0,
          total_amount: (item.outbound_qty || 0) * (item.unit_price || 0),
          reference_number: item.instruction_no,
          customer_code: item.customer_code,
          customer_name: item.customer_name,
          source_type: "shipment_instruction_detail",
          source_id: item.source_id || item.id,
          outbound_status: "대기",
        })),
      };

      const res = await apiClient.post("/outbound", payload);

      if (res.data?.success) {
        // Remove confirmed items from cart - direct DB delete for reliability
        const confirmedItems = [...selectedItemsList];
        const { dataApi } = await import("@/lib/api/data");
        const confirmPromises = confirmedItems
          .filter((item) => item.dbId)
          .map((item) => dataApi.updateRecord("cart_items", item.dbId, { status: "confirmed" }).catch(() => {}));
        await Promise.all(confirmPromises);

        // Also clean up local state via useCartSync
        for (const item of confirmedItems) {
          cart.removeItem(item.rowKey);
        }
        // Reload from DB to sync state
        await cart.loadFromDb();

        const outNo = finalNumber || "";

        setConfirmResult({
          outboundNumber: outNo,
          items: confirmedItems,
          warehouse: warehouses.find(w => w.warehouse_code === selectedWarehouse)?.warehouse_name || selectedWarehouse,
          date: outboundDate,
        });
        setResultMsg(null);
      } else {
        setResultMsg(
          `오류: ${res.data?.message || "출고 등록에 실패했습니다."}`
        );
      }
    } catch (err: unknown) {
      const msg =
        err instanceof Error ? err.message : "출고 등록에 실패했습니다.";
      setResultMsg(`오류: ${msg}`);
    } finally {
      setConfirming(false);
    }
  };

  /* ------------------------------------------------------------------ */
  /* Helpers                                                             */
  /* ------------------------------------------------------------------ */
  const selectedWarehouseName =
    warehouses.find((w) => w.warehouse_code === selectedWarehouse)
      ?.warehouse_name || selectedWarehouse;

  const totalQty = selectedItemsList.reduce((s, i) => s + i.outbound_qty, 0);

  /* ------------------------------------------------------------------ */
  /* Render                                                              */
  /* ------------------------------------------------------------------ */
  return (
    <div className="flex flex-col gap-4 pb-4">
      {/* ===== Header ===== */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <button
            onClick={() => router.back()}
            className="w-10 h-10 rounded-xl bg-white border border-gray-200 flex items-center justify-center text-gray-500 hover:bg-gray-50 active:scale-95 transition-all"
          >
            <svg
              className="w-5 h-5"
              fill="none"
              stroke="currentColor"
              strokeWidth={2}
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M15.75 19.5L8.25 12l7.5-7.5"
              />
            </svg>
          </button>
          <div>
            <h1 className="text-xl sm:text-2xl font-bold text-gray-900 tracking-tight">
              출고 장바구니
            </h1>
            {customerName && (
              <p className="text-xs text-gray-400 mt-0.5">{customerName}</p>
            )}
          </div>
        </div>

        {/* Confirm button (header only) */}
        <button
          onClick={handleConfirm}
          disabled={
            confirming ||
            selectedItemsList.length === 0 ||
            hasUnfinishedRequiredInspection
          }
          className="flex items-center gap-1.5 px-4 h-10 rounded-xl text-sm font-bold text-white active:scale-[0.98] transition-all disabled:opacity-40"
          style={{
            background:
              selectedItemsList.length > 0 && !hasUnfinishedRequiredInspection
                ? "linear-gradient(to bottom, #4ade80, #16a34a)"
                : "#d1d5db",
            boxShadow:
              selectedItemsList.length > 0 && !hasUnfinishedRequiredInspection
                ? "0 4px 12px rgba(22,163,74,0.3)"
                : "none",
          }}
        >
          <svg
            className="w-4 h-4"
            fill="none"
            stroke="currentColor"
            strokeWidth={2.5}
            viewBox="0 0 24 24"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              d="M4.5 12.75l6 6 9-13.5"
            />
          </svg>
          {confirming ? "처리중..." : "확정"}
        </button>
      </div>

      {/* ===== Info banner ===== */}
      <div className="bg-white rounded-xl border border-gray-100 shadow-sm p-3 sm:p-4">
        <div className="flex items-center gap-2 mb-3 pb-2 border-b border-gray-50">
          {customerName && (
            <span className="text-xs font-semibold text-green-700 bg-green-50 px-2 py-0.5 rounded-full">
              {customerName}
            </span>
          )}
          <span className="text-[11px] text-gray-400">
            {outboundDate}
          </span>
          {selectedWarehouseName && (
            <span className="text-[11px] text-gray-400">
              | {selectedWarehouseName}
            </span>
          )}
          <span className="ml-auto text-[11px] font-mono text-gray-400">
            {outboundNumber || "확정 시 자동생성"}
          </span>
        </div>

        {/* Info fields: 3 columns */}
        <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
          {/* Outbound date */}
          <div>
            <label className="text-[11px] font-semibold text-gray-400 mb-1 block">
              출고일자
            </label>
            <input
              type="date"
              value={outboundDate}
              onChange={(e) => setOutboundDate(e.target.value)}
              className="w-full px-3 py-2.5 border border-gray-200 rounded-lg text-sm outline-none focus:border-green-400 focus:ring-1 focus:ring-green-100 bg-white"
            />
          </div>

          {/* Warehouse selector */}
          <div>
            <label className="text-[11px] font-semibold text-gray-400 mb-1 block">
              창고
            </label>
            <button
              onClick={() => setWarehousePickerOpen(true)}
              className="w-full px-3 py-2.5 border border-gray-200 rounded-lg text-sm text-left outline-none hover:border-green-300 transition-all bg-white flex items-center justify-between"
            >
              <span className={selectedWarehouse ? "text-gray-900 font-medium" : "text-gray-400"}>
                {selectedWarehouseName || "창고 선택"}
              </span>
              <svg
                className="w-4 h-4 text-gray-400 shrink-0"
                fill="none"
                stroke="currentColor"
                strokeWidth={2}
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M8.25 15l3.75-3.75L15.75 15"
                />
              </svg>
            </button>
          </div>

          {/* Outbound number (readonly) */}
          <div>
            <label className="text-[11px] font-semibold text-gray-400 mb-1 block">
              출고번호
            </label>
            <div className="w-full px-3 py-2.5 border border-gray-200 rounded-lg text-sm bg-gray-50 font-mono">
              {outboundNumber ? (
                <span className="text-gray-700">{outboundNumber}</span>
              ) : (
                <span className="text-gray-400">확정 시 자동생성</span>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* ===== Select all bar ===== */}
      {items.length > 0 && (
        <div className="flex items-center justify-between px-1">
          <div className="flex items-center gap-2">
            <button
              onClick={toggleSelectAll}
              className={`w-6 h-6 rounded border-2 flex items-center justify-center transition-all shrink-0 ${
                selectedItems.size === items.length
                  ? "bg-green-500 border-green-500"
                  : "border-gray-300 hover:border-green-400"
              }`}
            >
              {selectedItems.size === items.length && (
                <svg
                  className="w-3.5 h-3.5 text-white"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth={3}
                  viewBox="0 0 24 24"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M4.5 12.75l6 6 9-13.5"
                  />
                </svg>
              )}
            </button>
            <span className="text-sm font-semibold text-gray-700">
              담은 품목{" "}
              <span className="text-green-600">{items.length}</span>
            </span>
          </div>

          <button
            onClick={toggleSelectAll}
            className="text-xs text-green-500 font-medium hover:underline"
          >
            {selectedItems.size === items.length ? "선택 해제" : "전체 선택"}
          </button>
        </div>
      )}

      {/* ===== Items list ===== */}
      {cart.loading ? (
        <div className="flex items-center justify-center py-16 text-sm text-gray-400">
          <svg
            className="animate-spin w-5 h-5 mr-2 text-green-500"
            fill="none"
            viewBox="0 0 24 24"
          >
            <circle
              className="opacity-25"
              cx="12"
              cy="12"
              r="10"
              stroke="currentColor"
              strokeWidth="4"
            />
            <path
              className="opacity-75"
              fill="currentColor"
              d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
            />
          </svg>
          불러오는 중...
        </div>
      ) : items.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-16 text-gray-400">
          <svg
            className="w-16 h-16 mb-4 opacity-20"
            fill="none"
            stroke="currentColor"
            strokeWidth={1}
            viewBox="0 0 24 24"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              d="M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 00-3 3h15.75m-12.75-3h11.218c1.121 0 2.002-.881 2.002-2.003V6.75m-14.22 0h14.22"
            />
          </svg>
          <p className="text-sm font-medium text-gray-500 mb-1">
            담은 품목이 없습니다
          </p>
          <p className="text-xs text-gray-400 mb-4">
            판매출고 화면에서 품목을 담아주세요
          </p>
          <button
            onClick={() => router.push("/pop/outbound/sales")}
            className="px-4 py-2.5 rounded-xl text-sm font-semibold text-white active:scale-95 transition-all"
            style={{
              background: "linear-gradient(to bottom, #4ade80, #16a34a)",
              boxShadow: "0 4px 12px rgba(34,197,94,0.3)",
            }}
          >
            판매출고로 이동
          </button>
        </div>
      ) : (
        <div className="flex flex-col gap-3">
          {items.map((item) => {
            const inspResult = getInspectionResult(item.rowKey);
            return (
              <div
                key={item.id}
                className={`relative rounded-xl border p-3 transition-all ${
                  selectedItems.has(item.id)
                    ? "border-green-300 bg-gradient-to-br from-green-50/80 to-emerald-50/50"
                    : "border-gray-200 bg-white"
                }`}
              >
                {/* Green left bar for selected items */}
                {selectedItems.has(item.id) && (
                  <div className="absolute top-0 left-0 w-[3px] h-full bg-green-500 rounded-l-xl" />
                )}

                {/* === Header row: checkbox + item code + item name + inspection badge === */}
                <div className="flex items-center gap-1.5 mb-2.5 pb-2 border-b border-gray-100">
                  {/* Checkbox */}
                  <button
                    onClick={() => toggleSelect(item.id)}
                    className={`w-6 h-6 rounded border-2 flex items-center justify-center transition-all shrink-0 ${
                      selectedItems.has(item.id)
                        ? "bg-green-500 border-green-500"
                        : "border-gray-300 hover:border-green-400"
                    }`}
                  >
                    {selectedItems.has(item.id) && (
                      <svg
                        className="w-3.5 h-3.5 text-white"
                        fill="none"
                        stroke="currentColor"
                        strokeWidth={3}
                        viewBox="0 0 24 24"
                      >
                        <path
                          strokeLinecap="round"
                          strokeLinejoin="round"
                          d="M4.5 12.75l6 6 9-13.5"
                        />
                      </svg>
                    )}
                  </button>
                  <span className="text-[11px] text-gray-400 font-medium shrink-0">{item.item_code}</span>
                  <span className="text-[13px] font-semibold text-gray-900 flex-1 truncate">{item.item_name}</span>
                  {item.inspection_type === "self" && (
                    <span className="text-[9px] font-bold px-1.5 py-0.5 rounded bg-blue-100 text-blue-700 border border-blue-200 shrink-0 whitespace-nowrap">
                      검사 필수
                    </span>
                  )}
                  {item.inspection_type === "request" && (
                    <span className="text-[9px] font-bold px-1.5 py-0.5 rounded bg-amber-100 text-amber-700 border border-amber-200 shrink-0 whitespace-nowrap">
                      검사의뢰 선택
                    </span>
                  )}
                </div>

                {/* === Body row: image + info + action === */}
                <div className="flex gap-2.5">
                  {/* Product image */}
                  <div className="w-[56px] h-[56px] min-w-[56px] bg-gray-50 border border-gray-200 rounded-lg flex items-center justify-center shrink-0 overflow-hidden">
                    {item.image ? (
                      <img src={item.image} alt={item.item_name} className="w-full h-full object-cover rounded-lg" />
                    ) : (
                      <span className="text-2xl text-gray-300">{"\uD83D\uDCE6"}</span>
                    )}
                  </div>

                  {/* Info columns */}
                  <div className="flex-1 min-w-0 flex flex-col gap-[3px]">
                    <div className="flex items-center gap-1.5 text-[11px]">
                      <span className="text-gray-400 min-w-[45px] shrink-0">지시일</span>
                      <span className="font-medium text-gray-700">{item.instruction_date || "-"}</span>
                    </div>
                    <div className="flex items-center gap-1.5 text-[11px]">
                      <span className="text-gray-400 min-w-[45px] shrink-0">지시번호</span>
                      <span className="font-medium text-gray-700 truncate">{item.instruction_no || "-"}</span>
                    </div>
                    <div className="flex items-center gap-1.5 text-[11px]">
                      <span className="text-gray-400 min-w-[45px] shrink-0">지시수량</span>
                      <span className="font-medium text-gray-700">{item.plan_qty.toLocaleString()}</span>
                    </div>
                    <div className="flex items-center gap-1.5 text-[11px]">
                      <span className="text-gray-400 min-w-[45px] shrink-0">미출고</span>
                      <span className="font-bold text-red-500">{item.remain_qty.toLocaleString()}</span>
                    </div>
                  </div>

                  {/* Action column: qty display + delete button */}
                  <div className="flex flex-col gap-1.5 items-stretch min-w-[80px] shrink-0">
                    {/* Qty display - clickable to open numpad */}
                    <button
                      onClick={() => openNumpad(item)}
                      className="flex items-center justify-center gap-1 px-2.5 py-2 rounded-md border transition-all bg-green-50 border-green-200 hover:bg-green-100 cursor-pointer active:scale-95"
                    >
                      <span
                        className="text-sm font-bold text-green-700"
                        style={{ fontVariantNumeric: "tabular-nums" }}
                      >
                        {item.outbound_qty.toLocaleString()}
                      </span>
                      <span className="text-[10px] text-gray-400">EA</span>
                    </button>

                    {/* Delete button */}
                    <button
                      onClick={() => handleRemove(item.rowKey)}
                      className="flex items-center justify-center gap-1 px-2.5 py-2 rounded-md bg-red-500 text-white text-xs font-semibold hover:bg-red-600 active:scale-95 transition-all"
                    >
                      <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                      </svg>
                      삭제
                    </button>
                  </div>
                </div>

                {/* === Package info === */}
                {item.packages && item.packages.length > 0 && (
                  <div className="mt-2.5 px-3 py-2 bg-gradient-to-r from-green-50 to-emerald-50 border border-green-200 rounded-lg">
                    <div className="flex items-center justify-between mb-1">
                      <span className="text-[10px] font-bold text-white bg-gradient-to-r from-green-500 to-green-600 px-2 py-0.5 rounded-full">
                        포장완료
                      </span>
                      <span className="text-[11px] font-semibold text-green-600">
                        {item.packages.reduce((s, p) => s + p.count * p.qtyPerUnit, 0).toLocaleString()} EA
                      </span>
                    </div>
                    {item.packages.map((pkg, idx) => (
                      <div key={idx} className="flex items-center gap-1.5 text-[11px] text-gray-600">
                        <span>{pkg.unit.icon}</span>
                        <span>{pkg.count}{pkg.unit.label} x {pkg.qtyPerUnit.toLocaleString()}EA = {(pkg.count * pkg.qtyPerUnit).toLocaleString()}EA</span>
                      </div>
                    ))}
                  </div>
                )}

                {/* === Inspection row === */}
                {(item.inspection_type === "self" ||
                  item.inspection_type === "request") && (
                  <div className="mt-2">
                    <div className="flex items-center gap-2">
                      <button
                        onClick={() => openInspection(item)}
                        className={`flex-1 flex items-center gap-2 px-3 py-2.5 rounded-lg border text-left transition-all active:scale-[0.98] ${
                          inspResult?.completed
                            ? "bg-green-50 border-green-300"
                            : item.inspection_type === "self"
                            ? "bg-blue-50 border-blue-200 hover:bg-blue-100"
                            : "bg-amber-50 border-amber-200 hover:bg-amber-100"
                        }`}
                      >
                        <span className="text-[13px] font-semibold">
                          {item.inspection_type === "self"
                            ? "검사"
                            : "검사의뢰"}
                        </span>
                        <span
                          className={`text-[11px] px-1.5 py-0.5 rounded ${
                            item.inspection_required
                              ? "bg-red-100 text-red-600"
                              : "bg-blue-100 text-blue-600"
                          }`}
                        >
                          {item.inspection_required ? "필수" : "선택"}
                        </span>
                        <span
                          className={`ml-auto text-[12px] font-semibold ${
                            inspResult?.completed
                              ? "text-green-600"
                              : "text-gray-400"
                          }`}
                        >
                          {inspResult?.completed ? "완료" : "대기"}
                        </span>
                        <svg
                          className="w-4 h-4 text-gray-400 shrink-0"
                          fill="none"
                          stroke="currentColor"
                          strokeWidth={2}
                          viewBox="0 0 24 24"
                        >
                          <path
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            d="M8.25 4.5l7.5 7.5-7.5 7.5"
                          />
                        </svg>
                      </button>

                      {!item.inspection_required &&
                        !inspResult?.completed && (
                          <button
                            onClick={() => handlePassInspection(item.rowKey)}
                            className="px-3 py-2.5 rounded-lg border border-gray-200 bg-gray-50 text-xs font-semibold text-gray-500 hover:bg-gray-100 active:scale-95 transition-all whitespace-nowrap"
                          >
                            패스
                          </button>
                        )}
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}

      {/* ===== Footer summary ===== */}
      {items.length > 0 && (
        <div className="sticky bottom-0 bg-white border-t border-gray-200 rounded-t-2xl shadow-lg -mx-4 px-4 sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8 py-4 mt-2">
          {resultMsg && (
            <div
              className={`mb-3 p-3 rounded-xl text-sm font-medium ${
                resultMsg.startsWith("오류")
                  ? "bg-red-50 text-red-700"
                  : "bg-green-50 text-green-700"
              }`}
            >
              {resultMsg}
            </div>
          )}

          {hasUnfinishedRequiredInspection && (
            <div className="mb-3 p-3 rounded-xl text-sm font-medium bg-amber-50 text-amber-700 border border-amber-200">
              필수 검사를 완료해주세요. 검사 미완료 품목이 있어 확정할 수 없습니다.
            </div>
          )}

          <div className="flex items-center justify-between text-sm">
            <span className="text-gray-500">
              선택{" "}
              <span className="font-bold text-gray-900">
                {selectedItemsList.length}
              </span>
              /{items.length}건
            </span>
            <span className="text-gray-500">
              합계 수량:{" "}
              <span className="font-bold text-green-600">
                {totalQty.toLocaleString()}
              </span>{" "}
              EA
            </span>
          </div>
        </div>
      )}

      {/* ===== Warehouse picker modal ===== */}
      {warehousePickerOpen && (
        <div className="fixed inset-0 z-50 flex items-end sm:items-center justify-center">
          <div
            className="absolute inset-0 bg-black/50"
            onClick={() => setWarehousePickerOpen(false)}
          />
          <div className="relative bg-white w-full sm:max-w-md sm:rounded-2xl rounded-t-2xl max-h-[80vh] flex flex-col shadow-2xl z-10 overflow-hidden">
            <div className="flex items-center justify-between px-5 py-4 border-b border-gray-100">
              <h3 className="text-lg font-bold text-gray-900">창고 선택</h3>
              <button
                onClick={() => setWarehousePickerOpen(false)}
                className="w-8 h-8 rounded-lg bg-gray-100 flex items-center justify-center text-gray-500 hover:bg-gray-200 transition-colors"
              >
                <svg
                  className="w-4 h-4"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth={2}
                  viewBox="0 0 24 24"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M6 18L18 6M6 6l12 12"
                  />
                </svg>
              </button>
            </div>

            <div className="flex-1 overflow-y-auto p-4">
              {warehouses.length === 0 ? (
                <p className="text-center text-sm text-gray-400 py-8">
                  등록된 창고가 없습니다
                </p>
              ) : (
                <div className="flex flex-col gap-2">
                  {warehouses.map((wh) => (
                    <button
                      key={wh.warehouse_code}
                      onClick={() => {
                        setSelectedWarehouse(wh.warehouse_code);
                        setWarehousePickerOpen(false);
                      }}
                      className={`flex items-center gap-3 p-4 rounded-xl border transition-all active:scale-[0.98] text-left ${
                        selectedWarehouse === wh.warehouse_code
                          ? "border-green-400 bg-green-50 shadow-sm"
                          : "border-gray-200 bg-white hover:border-green-300"
                      }`}
                    >
                      <div
                        className={`w-10 h-10 rounded-lg flex items-center justify-center shrink-0 ${
                          selectedWarehouse === wh.warehouse_code
                            ? "bg-green-500 text-white"
                            : "bg-gray-100 text-gray-400"
                        }`}
                      >
                        <svg
                          className="w-5 h-5"
                          fill="none"
                          stroke="currentColor"
                          strokeWidth={2}
                          viewBox="0 0 24 24"
                        >
                          <path
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            d="M2.25 21h19.5m-18-18v18m10.5-18v18m6-13.5V21M6.75 6.75h.75m-.75 3h.75m-.75 3h.75m3-6h.75m-.75 3h.75m-.75 3h.75M6.75 21v-3.375c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21M3 3h12m-.75 4.5H21m-3.75 0h.008v.008h-.008v-.008zm0 3h.008v.008h-.008v-.008zm0 3h.008v.008h-.008v-.008z"
                          />
                        </svg>
                      </div>
                      <div className="flex-1 min-w-0">
                        <p className="text-sm font-semibold text-gray-900">
                          {wh.warehouse_name}
                        </p>
                        <p className="text-[11px] text-gray-400">
                          {wh.warehouse_code}
                          {wh.warehouse_type ? ` | ${wh.warehouse_type}` : ""}
                        </p>
                      </div>
                      {selectedWarehouse === wh.warehouse_code && (
                        <svg
                          className="w-5 h-5 text-green-500 shrink-0"
                          fill="none"
                          stroke="currentColor"
                          strokeWidth={2.5}
                          viewBox="0 0 24 24"
                        >
                          <path
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            d="M4.5 12.75l6 6 9-13.5"
                          />
                        </svg>
                      )}
                    </button>
                  ))}
                </div>
              )}
            </div>
          </div>
        </div>
      )}

      {/* ===== Inspection Modal ===== */}
      {inspectionTarget && (
        <InspectionModal
          open={inspectionModalOpen}
          onClose={() => {
            setInspectionModalOpen(false);
            setInspectionTarget(null);
          }}
          onComplete={handleInspectionComplete}
          itemCode={inspectionTarget.item_code}
          itemName={inspectionTarget.item_name}
          totalQty={inspectionTarget.outbound_qty}
          initialResult={getInspectionResult(inspectionTarget.rowKey)}
        />
      )}

      {/* ===== NumberPad Modal (qty edit) ===== */}
      {numpadTarget && (
        <NumberPadModal
          open={numpadOpen}
          onClose={() => {
            setNumpadOpen(false);
            setNumpadTarget(null);
          }}
          onConfirm={handleNumpadConfirm}
          maxQty={numpadTarget.remain_qty}
          itemName={numpadTarget.item_name}
          initialQty={numpadTarget.outbound_qty}
          initialPackages={numpadTarget.packages}
        />
      )}

      {/* ===== 출고 완료 결과 모달 ===== */}
      {confirmResult && (
        <div className="fixed inset-0 z-[70] flex items-center justify-center">
          <div className="absolute inset-0 bg-black/50" />
          <div className="relative bg-white rounded-2xl shadow-2xl w-full max-w-md mx-4 overflow-hidden z-10">
            {/* Header */}
            <div className="px-6 py-5 text-center" style={{ background: "linear-gradient(to bottom, #4ade80, #16a34a)" }}>
              <div className="w-14 h-14 rounded-full bg-white/20 flex items-center justify-center mx-auto mb-3">
                <svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
                </svg>
              </div>
              <h3 className="text-xl font-bold text-white">출고 처리 완료</h3>
              <p className="text-white/80 text-lg font-mono mt-1">{confirmResult.outboundNumber}</p>
            </div>

            {/* Details */}
            <div className="px-6 py-4">
              <div className="flex items-center justify-between text-sm text-gray-500 mb-3">
                <span>창고: <span className="font-semibold text-gray-900">{confirmResult.warehouse}</span></span>
                <span>{confirmResult.date}</span>
              </div>

              <div className="text-xs font-semibold text-gray-400 mb-2">처리된 품목 ({confirmResult.items.length}건)</div>
              <div className="max-h-[200px] overflow-y-auto flex flex-col gap-2">
                {confirmResult.items.map((item) => (
                  <div key={item.id} className="flex items-center justify-between p-3 bg-green-50 rounded-xl border border-green-100">
                    <div className="flex-1 min-w-0">
                      <p className="text-sm font-semibold text-gray-900 truncate">{item.item_name}</p>
                      <p className="text-[11px] text-gray-400">{item.item_code}</p>
                    </div>
                    <span className="text-sm font-bold text-green-600 ml-3">{item.outbound_qty?.toLocaleString()} EA</span>
                  </div>
                ))}
              </div>
            </div>

            {/* OK button */}
            <div className="px-6 py-4 border-t border-gray-100">
              <button
                onClick={() => {
                  setConfirmResult(null);
                  router.push("/pop/outbound");
                }}
                className="w-full h-12 rounded-xl text-white font-bold text-base active:scale-[0.98] transition-all"
                style={{ background: "linear-gradient(to bottom, #4ade80, #16a34a)", boxShadow: "0 4px 12px rgba(34,197,94,.3)" }}
              >
                확인
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
