"use client";

import { useEffect, useState, useCallback } from "react";
import { Save, RefreshCcw, CheckCircle2, Clock } from "lucide-react";
import Swal from "sweetalert2";

interface ProcRow {
  OBJID: string; PROC_NO: string; PROC_DATE: string;
  VENDOR_OBJID: string | null; VENDOR_NAME: string | null;
  STATUS: string; TOTAL_AMOUNT: number; LINE_CNT: number;
  TOTAL_QTY: number; RECEIVED_QTY: number;
}
interface ProcDetail { OBJID: string; PROC_NO: string; PROC_DATE: string; STATUS: string; VENDOR_NAME: string | null }
interface ProcLine {
  OBJID: string; ITEM_OBJID: string; ITEM_CODE: string; ITEM_NAME: string;
  UNIT: string; QTY: number; COST_PRICE: number;
  RECEIVED_QTY: number; RECEIVED_NORMAL: number; RECEIVED_DEFECT: number;
}
interface Warehouse { OBJID: string; WH_NAME: string }

const fmt = (n: number | string | undefined) => Number(n || 0).toLocaleString("ko-KR");
const STATUS_LABEL: Record<string, string> = {
  REQUESTED: "발주요청", PAID: "입금완료", PARTIAL: "입고중", RECEIVED: "입고완료", OPEN: "작성중", CANCELLED: "취소",
};
const STATUS_COLOR: Record<string, string> = {
  OPEN:      "bg-slate-100 text-slate-600 border-slate-200",
  REQUESTED: "bg-amber-100 text-amber-700 border-amber-200",
  PAID:      "bg-emerald-100 text-emerald-700 border-emerald-200",
  PARTIAL:   "bg-orange-100 text-orange-700 border-orange-200",
  RECEIVED:  "bg-emerald-100 text-emerald-800 border-emerald-300",
  CANCELLED: "bg-rose-100 text-rose-600 border-rose-200",
};

export default function InboundsPage() {
  const [list, setList] = useState<ProcRow[]>([]);
  const [statusFilter, setStatusFilter] = useState("PAID_OR_PARTIAL");
  const [activeId, setActiveId] = useState("");
  const [detail, setDetail] = useState<{ proc: ProcDetail; items: ProcLine[] } | null>(null);
  const [warehouses, setWarehouses] = useState<Warehouse[]>([]);
  const [busy, setBusy] = useState(false);

  // 라인별 입력 (창고/입고수량/불량수량)
  const [inputs, setInputs] = useState<Record<string, { whObjid: string; qtyNormal: number; qtyDefect: number }>>({});

  const load = useCallback(async () => {
    const body: Record<string, unknown> = {};
    // 입고 화면은 REQUESTED + PARTIAL 만 보이게
    const res = await fetch("/api/m/procurements/list", {
      method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body),
    });
    const j = await res.json();
    let rows: ProcRow[] = j.RESULTLIST ?? [];
    // 입고 처리 대상: 입금완료(PAID) 또는 입고중(PARTIAL) 만 (REQUESTED 는 입금 전이라 입고 불가)
    if (statusFilter === "PAID_OR_PARTIAL") {
      rows = rows.filter((r) => r.STATUS === "PAID" || r.STATUS === "PARTIAL");
    } else if (statusFilter && statusFilter !== "ALL") {
      rows = rows.filter((r) => r.STATUS === statusFilter);
    }
    setList(rows);
    if (rows.length && !rows.some((r) => r.OBJID === activeId)) setActiveId(rows[0].OBJID);
    if (!rows.length) { setActiveId(""); setDetail(null); }
  }, [statusFilter, activeId]);

  const loadWh = async () => {
    const r = await fetch("/api/m/warehouses/list", { method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" });
    setWarehouses((await r.json()).RESULTLIST ?? []);
  };

  const loadDetail = useCallback(async () => {
    if (!activeId) { setDetail(null); return; }
    const res = await fetch("/api/m/procurements/detail", {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ objid: activeId }),
    });
    const j = await res.json();
    if (j.success) {
      setDetail({ proc: j.proc, items: j.items });
      // 입력 칸 초기화 — 창고는 첫 창고 / 수량은 남은 만큼
      const next: Record<string, { whObjid: string; qtyNormal: number; qtyDefect: number }> = {};
      const defaultWh = warehouses[0]?.OBJID ?? "";
      for (const it of j.items) {
        const remaining = Number(it.QTY) - Number(it.RECEIVED_QTY ?? 0);
        next[it.OBJID] = { whObjid: defaultWh, qtyNormal: Math.max(0, remaining), qtyDefect: 0 };
      }
      setInputs(next);
    }
  }, [activeId, warehouses]);

  useEffect(() => { loadWh(); }, []);
  useEffect(() => { load(); }, [load]);
  useEffect(() => { loadDetail(); }, [loadDetail]);

  const updateInput = (lineObjid: string, patch: Partial<{ whObjid: string; qtyNormal: number; qtyDefect: number }>) => {
    setInputs((p) => ({ ...p, [lineObjid]: { ...p[lineObjid], ...patch } }));
  };

  const submitInbound = async () => {
    if (!detail) return;

    // 모든 라인에 동일한 창고를 사용한다고 가정 (라인별 다른 창고 가능하게도 만들 수 있음 — 단, save API 는 단일 whObjid 받음)
    // 라인별 창고가 다르면 여러 번 호출. 여기서는 단순화: 첫 라인의 창고를 대표 창고로.
    const linesToSend = detail.items
      .map((it) => {
        const inp = inputs[it.OBJID];
        if (!inp) return null;
        const qN = Number(inp.qtyNormal) || 0;
        const qD = Number(inp.qtyDefect) || 0;
        if (qN + qD === 0) return null;
        const remaining = Number(it.QTY) - Number(it.RECEIVED_QTY ?? 0);
        if (qN + qD > remaining) return { error: `${it.ITEM_NAME} — 남은 수량(${remaining}) 초과` };
        return {
          itemObjid: it.ITEM_OBJID,
          qtyNormal: qN,
          qtyDefect: qD,
          costPrice: Number(it.COST_PRICE),
        };
      })
      .filter(Boolean) as ({ itemObjid: string; qtyNormal: number; qtyDefect: number; costPrice: number } | { error: string })[];

    const errLine = linesToSend.find((l) => "error" in l);
    if (errLine) {
      Swal.fire({ icon: "warning", title: (errLine as { error: string }).error });
      return;
    }
    const cleanLines = linesToSend.filter((l): l is { itemObjid: string; qtyNormal: number; qtyDefect: number; costPrice: number } => !("error" in l));
    if (cleanLines.length === 0) {
      Swal.fire({ icon: "warning", title: "입고할 수량을 입력하세요." });
      return;
    }

    // 라인별 창고가 다를 수 있으니 창고별로 그룹핑
    const byWh = new Map<string, typeof cleanLines>();
    for (const ln of cleanLines) {
      const lineDef = detail.items.find((it) => it.ITEM_OBJID === ln.itemObjid);
      const inp = inputs[lineDef?.OBJID ?? ""];
      const wh = inp?.whObjid;
      if (!wh) {
        Swal.fire({ icon: "warning", title: `${lineDef?.ITEM_NAME} — 창고를 선택하세요.` });
        return;
      }
      if (!byWh.has(wh)) byWh.set(wh, []);
      byWh.get(wh)!.push(ln);
    }

    const ok = await Swal.fire({
      icon: "question", title: "입고 처리하시겠습니까?",
      html: `매입발주 <b>${detail.proc.PROC_NO}</b><br>총 ${cleanLines.length}개 라인 입고`,
      showCancelButton: true, confirmButtonText: "입고", cancelButtonText: "취소",
      confirmButtonColor: "#0f766e",
    });
    if (!ok.isConfirmed) return;

    setBusy(true);
    let successCnt = 0, failCnt = 0;
    const errors: string[] = [];
    for (const [whObjid, whLines] of byWh.entries()) {
      try {
        const res = await fetch("/api/m/inbounds/save", {
          method: "POST", headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            procObjid: detail.proc.OBJID,
            whObjid,
            lines: whLines,
          }),
        });
        const j = await res.json();
        if (j.success) successCnt++;
        else { failCnt++; errors.push(j.message); }
      } catch (err) {
        failCnt++;
        errors.push(err instanceof Error ? err.message : "오류");
      }
    }
    setBusy(false);

    Swal.fire({
      icon: failCnt === 0 ? "success" : "warning",
      title: `입고 처리 완료 (성공 ${successCnt} / 실패 ${failCnt})`,
      html: errors.length > 0 ? errors.join("<br>") : "재고가 자동으로 늘어났습니다.",
    });
    load();
    loadDetail();
  };

  return (
    <div className="space-y-3">
      <div className="flex items-end justify-between flex-wrap gap-2">
        <div>
          <h1 className="text-xl font-bold">입고 처리</h1>
          <p className="text-xs text-slate-500 mt-0.5">입금완료된 발주만 표시됩니다. 왼쪽에서 발주서를 선택하고, 오른쪽에서 라인별 창고/입고수량을 입력하세요. 부분 입고 가능.</p>
        </div>
        <div className="flex gap-2">
          <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}
            className="h-9 px-3 rounded border border-slate-300 bg-white text-sm">
            <option value="PAID_OR_PARTIAL">입고 가능 (입금완료 + 입고중)</option>
            <option value="ALL">전체</option>
            <option value="PAID">입금완료만</option>
            <option value="PARTIAL">입고중만</option>
            <option value="RECEIVED">입고완료</option>
          </select>
          <button onClick={load} className="h-9 px-3 rounded bg-white border border-slate-300 text-sm font-semibold inline-flex items-center gap-1">
            <RefreshCcw size={14} /> 조회
          </button>
        </div>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-[400px_1fr] gap-3">
        {/* 좌: 매입 발주 리스트 */}
        <div className="bg-white border border-slate-200 rounded-xl overflow-hidden">
          <div className="px-3 py-2 bg-slate-50 border-b border-slate-200 text-xs font-semibold text-slate-600">
            발주서 목록 ({list.length}건)
          </div>
          <div className="overflow-x-auto max-h-[60vh] lg:max-h-[calc(100vh-220px)]">
            <table className="w-full text-xs">
              <thead className="bg-slate-50 text-slate-500">
                <tr>
                  <th className="text-left px-2 py-2">발주번호</th>
                  <th className="text-left px-2 py-2">공급업체</th>
                  <th className="text-center px-2 py-2">발주/입고/미입고</th>
                  <th className="text-center px-2 py-2">상태</th>
                </tr>
              </thead>
              <tbody>
                {list.length === 0 ? (
                  <tr><td colSpan={4} className="text-center py-12 text-slate-400">입고 가능한 발주서가 없습니다.</td></tr>
                ) : list.map((p) => {
                  const total = Number(p.TOTAL_QTY);
                  const recv = Number(p.RECEIVED_QTY);
                  const remain = Math.max(0, total - recv);
                  return (
                    <tr key={p.OBJID}
                        onClick={() => setActiveId(p.OBJID)}
                        style={{ cursor: "pointer" }}
                        className={`border-t border-slate-100 ${activeId === p.OBJID ? "bg-emerald-50" : "hover:bg-slate-50"}`}>
                      <td className="px-2 py-2 font-semibold">{p.PROC_NO}<div className="text-slate-400 text-[10px]">{p.PROC_DATE}</div></td>
                      <td className="px-2 py-2 truncate max-w-[120px]">{p.VENDOR_NAME ?? <span className="text-slate-300">미선택</span>}</td>
                      <td className="px-2 py-2 text-center text-[11px] tabular-nums">
                        <span className="text-slate-700">{fmt(total)}</span>
                        <span className="text-slate-300 mx-0.5">/</span>
                        <span className="text-emerald-700 font-semibold">{fmt(recv)}</span>
                        {remain > 0 && (<>
                          <span className="text-slate-300 mx-0.5">/</span>
                          <span className="text-rose-600 font-semibold">{fmt(remain)}</span>
                        </>)}
                      </td>
                      <td className="px-2 py-2 text-center">
                        <span className={`inline-block px-1.5 py-0.5 rounded text-[10px] font-semibold border ${STATUS_COLOR[p.STATUS] ?? "bg-slate-100 text-slate-500 border-slate-200"}`}>
                          {STATUS_LABEL[p.STATUS] ?? p.STATUS}
                        </span>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>

        {/* 우: 입고 입력 폼 */}
        <div className="bg-white border border-slate-200 rounded-xl overflow-hidden flex flex-col">
          <div className="px-3 py-2 bg-slate-50 border-b border-slate-200 text-xs font-semibold text-slate-600 flex items-center justify-between">
            <span>입고 처리 입력</span>
            {detail && (detail.proc.STATUS === "PAID" || detail.proc.STATUS === "PARTIAL") && (
              <button onClick={submitInbound} disabled={busy}
                className="inline-flex items-center gap-1 h-8 px-3 rounded bg-emerald-700 text-white text-xs font-bold hover:bg-emerald-800 disabled:opacity-50">
                <Save size={12} /> 입고 등록
              </button>
            )}
            {detail && detail.proc.STATUS === "RECEIVED" && (
              <span className="text-[11px] text-emerald-700 inline-flex items-center gap-1">
                <CheckCircle2 size={12} /> 입고 완료
              </span>
            )}
          </div>
          <div className="flex-1 lg:overflow-auto p-4">
            {!detail ? (
              <div className="h-full flex items-center justify-center text-slate-400">왼쪽에서 매입 발주서를 선택하세요.</div>
            ) : (
              <InboundForm
                detail={detail}
                warehouses={warehouses}
                inputs={inputs}
                onUpdate={updateInput}
              />
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function InboundForm({ detail, warehouses, inputs, onUpdate }: {
  detail: { proc: ProcDetail; items: ProcLine[] };
  warehouses: Warehouse[];
  inputs: Record<string, { whObjid: string; qtyNormal: number; qtyDefect: number }>;
  onUpdate: (lineObjid: string, patch: Partial<{ whObjid: string; qtyNormal: number; qtyDefect: number }>) => void;
}) {
  const editable = detail.proc.STATUS === "PAID" || detail.proc.STATUS === "PARTIAL";
  return (
    <div className="text-[12px]">
      <div className="flex items-center justify-between mb-3">
        <div>
          <div className="text-base font-bold">{detail.proc.PROC_NO}</div>
          <div className="text-xs text-slate-500">발주일 {detail.proc.PROC_DATE} · 공급업체 {detail.proc.VENDOR_NAME ?? "-"}</div>
        </div>
        <span className={`inline-flex items-center gap-1 text-xs px-2 py-1 rounded border ${STATUS_COLOR[detail.proc.STATUS]}`}>
          {detail.proc.STATUS === "PARTIAL" ? <Clock size={12} /> : detail.proc.STATUS === "RECEIVED" ? <CheckCircle2 size={12} /> : null}
          {STATUS_LABEL[detail.proc.STATUS] ?? detail.proc.STATUS}
        </span>
      </div>

      {!editable && (
        <div className="border border-slate-200 bg-slate-50 rounded p-2 text-[11px] text-slate-600 mb-2">
          이 발주서는 {STATUS_LABEL[detail.proc.STATUS]} 상태라 입고 입력이 불가합니다.
        </div>
      )}

      <table className="w-full text-[11px] border border-slate-300" style={{borderCollapse:'collapse'}}>
        <thead className="bg-slate-100">
          <tr>
            <th className="border border-slate-300 px-1 py-1.5 w-8">#</th>
            <th className="border border-slate-300 px-2 py-1.5 text-left">품목</th>
            <th className="border border-slate-300 px-1 py-1.5 w-16">발주</th>
            <th className="border border-slate-300 px-1 py-1.5 w-16">기입고</th>
            <th className="border border-slate-300 px-1 py-1.5 w-16">남은</th>
            <th className="border border-slate-300 px-1 py-1.5 w-32">창고</th>
            <th className="border border-slate-300 px-1 py-1.5 w-20">정상 입고</th>
            <th className="border border-slate-300 px-1 py-1.5 w-20">불량</th>
          </tr>
        </thead>
        <tbody className="tabular-nums">
          {detail.items.length === 0 ? (
            <tr><td colSpan={8} className="border border-slate-300 px-2 py-6 text-center text-slate-400">발주 라인이 없습니다.</td></tr>
          ) : detail.items.map((it, idx) => {
            const total = Number(it.QTY);
            const recv = Number(it.RECEIVED_QTY ?? 0);
            const remain = Math.max(0, total - recv);
            const inp = inputs[it.OBJID] ?? { whObjid: "", qtyNormal: 0, qtyDefect: 0 };
            const fullyReceived = remain === 0;
            return (
              <tr key={it.OBJID} className={fullyReceived ? "bg-emerald-50/40" : "bg-white"}>
                <td className="border border-slate-300 px-1 py-1 text-center">{idx + 1}</td>
                <td className="border border-slate-300 px-2 py-1">
                  {it.ITEM_NAME} <span className="text-slate-400">[{it.ITEM_CODE}]</span>
                  {fullyReceived && <span className="ml-2 text-[10px] text-emerald-700 font-bold">✓ 완료</span>}
                </td>
                <td className="border border-slate-300 px-1 py-1 text-right">{fmt(total)}</td>
                <td className="border border-slate-300 px-1 py-1 text-right text-emerald-700">{fmt(recv)}</td>
                <td className={`border border-slate-300 px-1 py-1 text-right ${remain > 0 ? "text-rose-600 font-bold" : "text-slate-400"}`}>{fmt(remain)}</td>
                <td className="border border-slate-300 px-1 py-1">
                  {editable && !fullyReceived ? (
                    <select
                      value={inp.whObjid}
                      onChange={(e) => onUpdate(it.OBJID, { whObjid: e.target.value })}
                      className="w-full h-7 px-1 border border-slate-200 rounded text-[11px] bg-white">
                      <option value="">-- 선택 --</option>
                      {warehouses.map((w) => <option key={w.OBJID} value={w.OBJID}>{w.WH_NAME}</option>)}
                    </select>
                  ) : <span className="text-slate-400">-</span>}
                </td>
                <td className="border border-slate-300 px-1 py-1">
                  {editable && !fullyReceived ? (
                    <input type="number" min={0} max={remain} value={inp.qtyNormal}
                      onChange={(e) => {
                        const v = Math.min(remain, Math.max(0, Number(e.target.value) || 0));
                        onUpdate(it.OBJID, { qtyNormal: v });
                      }}
                      className="w-full h-7 px-1 border border-slate-200 rounded text-[11px] text-right tabular-nums bg-white" />
                  ) : <span className="text-slate-400">-</span>}
                </td>
                <td className="border border-slate-300 px-1 py-1">
                  {editable && !fullyReceived ? (
                    <input type="number" min={0} max={remain} value={inp.qtyDefect}
                      onChange={(e) => {
                        const v = Math.min(remain, Math.max(0, Number(e.target.value) || 0));
                        onUpdate(it.OBJID, { qtyDefect: v });
                      }}
                      className="w-full h-7 px-1 border border-slate-200 rounded text-[11px] text-right tabular-nums bg-white" />
                  ) : <span className="text-slate-400">-</span>}
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>

      {editable && (
        <div className="mt-3 text-[11px] text-slate-500">
          ※ 정상 입고 + 불량은 <b>남은 수량 이하</b>로만 입력 가능합니다. 0으로 두면 그 라인은 입고하지 않습니다.<br />
          ※ 일부 라인만 입고하면 발주서가 <span className="inline-block px-1.5 py-0.5 rounded bg-orange-100 text-orange-700 font-bold">입고중</span>으로 표시되고, 나중에 다시 들어와 마저 입고할 수 있어요.
        </div>
      )}
    </div>
  );
}
