"use client";

import { useState, useCallback, useEffect, useMemo } from "react";
import { SearchForm, SearchField } from "@/components/layout/search-form";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { SearchableSelect } from "@/components/ui/searchable-select";
import { FolderCell } from "@/components/ui/folder-cell";
import { ExcelDownloadButton } from "@/components/ui/excel-download-button";
import type { ExcelColumn } from "@/lib/excel-export";
import Swal from "sweetalert2";

type Row = Record<string, unknown>;
type CodeOpt = { CODE_ID: string; CODE_NAME: string };

// 제품관리_설변대상 PART조회 (원본: partMng/partMngChangeList.jsp)
export default function PartChangePage() {
  const [projectName, setProjectName] = useState("");
  const [unitCode, setUnitCode] = useState("");
  const [searchPartObjid, setSearchPartObjid] = useState("");

  const [data, setData] = useState<Row[]>([]);
  const [loading, setLoading] = useState(false);
  const [projects, setProjects] = useState<{ value: string; label: string }[]>([]);
  const [units, setUnits] = useState<{ value: string; label: string }[]>([]);
  const [parts, setParts] = useState<{ value: string; label: string }[]>([]);

  const [partTypes, setPartTypes] = useState<CodeOpt[]>([]);
  const [changeTypes, setChangeTypes] = useState<CodeOpt[]>([]);
  const [changeOptions, setChangeOptions] = useState<CodeOpt[]>([]);

  // 공통코드 로드 (API 응답이 소문자 키라 대문자로 정규화)
  useEffect(() => {
    const loadCode = async (codeId: string): Promise<CodeOpt[]> => {
      const res = await fetch("/api/common/code-list", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ codeId }),
      });
      const j = await res.json();
      return (j.data || []).map((r: Record<string, unknown>) => ({
        CODE_ID: String(r.code_id || r.CODE_ID || ""),
        CODE_NAME: String(r.code_name || r.CODE_NAME || ""),
      }));
    };
    loadCode("0000062").then(setPartTypes);
    loadCode("0001054").then(setChangeTypes); // PART_CHANGE_TYPE_CODE
    loadCode("0000318").then(setChangeOptions); // PART_CHANGE_OPTION_CODE
  }, []);

  // 프로젝트 목록
  useEffect(() => {
    fetch("/api/common/project-list", {
      method: "POST", headers: { "Content-Type": "application/json" }, body: "{}",
    }).then((r) => r.json())
      .then((j) => setProjects((j.RESULTLIST || []).map((r: Row) => ({
        value: String(r.OBJID), label: String(r.LABEL || r.PROJECT_NO || r.OBJID),
      }))))
      .catch(() => {});
  }, []);

  // 프로젝트 변경 시 유닛
  useEffect(() => {
    setUnitCode("");
    setSearchPartObjid("");
    if (!projectName) { setUnits([]); return; }
    fetch("/api/common/unit-list", {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ contract_objid: projectName }),
    }).then((r) => r.json())
      .then((j) => setUnits((j.RESULTLIST || []).map((r: Row) => ({
        value: String(r.OBJID), label: String(r.UNIT_NAME || r.TASK_NAME),
      }))))
      .catch(() => {});
  }, [projectName]);

  // 유닛 변경 시 PART 목록
  useEffect(() => {
    setSearchPartObjid("");
    if (!projectName || !unitCode) { setParts([]); return; }
    fetch("/api/product/part-change", {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action: "list", project_name: projectName, unit_code: unitCode }),
    }).then((r) => r.json())
      .then((j) => {
        const uniq = new Map<string, string>();
        (j.RESULTLIST || []).forEach((r: Row) => {
          const id = String(r.OBJID);
          uniq.set(id, `${r.PART_NO ?? ""} ${r.PART_NAME ?? ""}`);
        });
        setParts([...uniq.entries()].map(([value, label]) => ({ value, label })));
      })
      .catch(() => {});
  }, [projectName, unitCode]);

  const fetchData = useCallback(async () => {
    if (!projectName) {
      Swal.fire("알림", "프로젝트번호를 선택하세요.", "warning");
      return;
    }
    if (!unitCode) {
      Swal.fire("알림", "유닛명을 선택하세요.", "warning");
      return;
    }
    if (!searchPartObjid) {
      Swal.fire("알림", "품번을 선택하세요.", "warning");
      return;
    }
    setLoading(true);
    try {
      const res = await fetch("/api/product/part-change", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          action: "list",
          project_name: projectName,
          unit_code: unitCode,
          SEARCH_PART_OBJID: searchPartObjid,
        }),
      });
      if (res.ok) {
        const j = await res.json();
        setData(j.RESULTLIST || []);
      }
    } finally {
      setLoading(false);
    }
  }, [projectName, unitCode, searchPartObjid]);

  const updateCell = (idx: number, field: string, value: string) => {
    setData((prev) => {
      const next = [...prev];
      next[idx] = { ...next[idx], [field]: value };
      // 같은 품번끼리 동기화 (원본 cellEdited 동작)
      const partNo = next[idx].PART_NO;
      for (let i = 0; i < next.length; i++) {
        if (i !== idx && next[i].PART_NO === partNo) {
          next[i] = { ...next[i], [field]: value };
        }
      }
      return next;
    });
  };

  // 같은 PART_NO가 여러 행(동시 적용 BOM)으로 올 때 첫 번째만 편집 가능.
  // updateCell 이 같은 PART_NO 나머지 행도 동기화하므로 하나만 활성화해도 충분.
  const editableIdxSet = useMemo(() => {
    const seen = new Set<string>();
    const s = new Set<number>();
    data.forEach((row, idx) => {
      if (String(row.Q_STATUS || "") !== "deploy") return;
      const partNo = String(row.PART_NO ?? "");
      if (!seen.has(partNo)) {
        seen.add(partNo);
        s.add(idx);
      }
    });
    return s;
  }, [data]);

  const isEditable = (idx: number) => editableIdxSet.has(idx);

  const handleSave = async () => {
    if (data.length === 0) {
      Swal.fire("알림", "저장할 데이터가 없습니다.", "warning");
      return;
    }
    const allDeploy = data.every((r) => String(r.Q_STATUS || "") === "deploy");
    if (!allDeploy) {
      Swal.fire("알림", "설변중인 파트입니다. 배포후에 다시 설계변경 할 수 있습니다.", "warning");
      return;
    }
    const allFilled = data.every((r) =>
      String(r.CHANGE_TYPE || "") !== "" && String(r.CHANGE_OPTION || "") !== ""
    );
    if (!allFilled) {
      Swal.fire("알림", "EO구분, EO사유는 필수 입력입니다.", "warning");
      return;
    }
    const c = await Swal.fire({
      title: "저장하시겠습니까?", icon: "question", showCancelButton: true,
      confirmButtonText: "확인", cancelButtonText: "취소",
    });
    if (!c.isConfirmed) return;
    const res = await fetch("/api/product/part-change", {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action: "save", rows: data }),
    });
    const j = await res.json();
    if (j.success) {
      await Swal.fire({ icon: "success", title: j.message, timer: 1200, showConfirmButton: false });
      fetchData();
    } else {
      Swal.fire("오류", j.message || "저장 실패", "error");
    }
  };

  const openPartForm = (objId: string) => {
    const w = 600, h = 500;
    const left = (window.screen.width - w) / 2;
    const top = (window.screen.height - h) / 2;
    window.open(`/product/popup/part-form?objId=${encodeURIComponent(objId)}`, "partMngPopUp",
      `width=${w},height=${h},left=${left},top=${top}`);
  };

  const openFilePopup = (objId: string, docType: string, docTypeName: string) => {
    const w = 800, h = 335;
    const left = (window.screen.width - w) / 2;
    const top = (window.screen.height - h) / 2;
    window.open(
      `/common/files?targetObjId=${encodeURIComponent(objId)}&docType=${encodeURIComponent(docType)}&docTypeName=${encodeURIComponent(docTypeName)}`,
      "fileRegistPopUp", `width=${w},height=${h},left=${left},top=${top}`,
    );
  };

  const yellowHeader = "px-2 py-1 text-[#FFBB00] border border-gray-200 font-semibold text-center whitespace-nowrap";
  const normalHeader = "px-2 py-1 border border-gray-200 font-semibold text-center whitespace-nowrap";
  // frozen 셀/헤더 공통 스타일 — 인라인 스타일로 sticky/bg/zIndex 강제 적용 (border-collapse:separate 와 조합)
  const freezeHeader = (left: number): React.CSSProperties => ({
    position: "sticky", left, top: 0, zIndex: 30, backgroundColor: "#F9FAFB",
  });
  const freezeCell = (left: number): React.CSSProperties => ({
    position: "sticky", left, zIndex: 20, backgroundColor: "#FFFFFF",
  });

  // Excel 컬럼 정의 (원본 partMngChangeList 헤더 순서 그대로)
  const excelColumns: ExcelColumn[] = useMemo(() => {
    const codeName = (list: CodeOpt[], id: string) =>
      list.find((c) => c.CODE_ID === id)?.CODE_NAME ?? id;
    return [
      { title: "프로젝트번호", field: "PROJECT_NO" },
      { title: "유닛명", field: "UNIT_NAME" },
      { title: "모품번", field: "PARENT_PART_INFO" },
      { title: "품번", field: "PART_NO" },
      { title: "품명", field: "PART_NAME" },
      { title: "수량", field: "Q_QTY" },
      { title: "3D", excelFormatter: (r) => Number(r.CU01_CNT ?? 0) },
      { title: "2D", excelFormatter: (r) => Number(r.CU02_CNT ?? 0) },
      { title: "PDF", excelFormatter: (r) => Number(r.CU03_CNT ?? 0) },
      { title: "EO구분", excelFormatter: (r) => codeName(changeTypes, String(r.CHANGE_TYPE ?? "")) },
      { title: "EO사유", excelFormatter: (r) => codeName(changeOptions, String(r.CHANGE_OPTION ?? "")) },
      { title: "PART구분", excelFormatter: (r) => codeName(partTypes, String(r.PART_TYPE ?? "")) },
      { title: "재질", field: "MATERIAL" },
      { title: "사양(규격)", field: "SPEC" },
      { title: "후처리", field: "POST_PROCESSING" },
      { title: "MAKER", field: "MAKER" },
      { title: "대분류", field: "MAJOR_CATEGORY" },
      { title: "중분류", field: "SUB_CATEGORY" },
      { title: "Revision", field: "REVISION" },
      { title: "EO No", field: "EO_NO" },
      { title: "EO Date", field: "EO_DATE" },
      { title: "비고", field: "REMARK" },
    ];
  }, [changeTypes, changeOptions, partTypes]);

  const codeSel = useMemo(() => (opts: CodeOpt[], val: string, onChange: (v: string) => void, disabled: boolean) => (
    <select value={val || ""} onChange={(e) => onChange(e.target.value)} disabled={disabled}
      className="w-full h-7 text-xs border border-gray-300 rounded px-1 disabled:bg-gray-100">
      <option value="">선택</option>
      {opts.map((o) => <option key={o.CODE_ID} value={o.CODE_ID}>{o.CODE_NAME}</option>)}
    </select>
  ), []);

  return (
    <div>
      <div className="flex items-center justify-between mb-4">
        <h2 className="text-lg font-bold text-gray-800">제품관리_설변대상 PART조회</h2>
        <div className="flex gap-2">
          <Button size="sm" onClick={handleSave}>설계변경저장</Button>
          <Button size="sm" onClick={fetchData}>조회</Button>
          <ExcelDownloadButton
            data={data}
            columns={excelColumns}
            filename="제품관리_설변대상PART조회"
            sheetName="설변대상PART"
          />
          <Button size="sm" variant="secondary" onClick={() => {
            setProjectName(""); setUnitCode(""); setSearchPartObjid(""); setData([]);
          }}>초기화</Button>
        </div>
      </div>

      <SearchForm onSearch={fetchData}>
        <SearchField label="프로젝트번호">
          <SearchableSelect options={projects} value={projectName} onChange={setProjectName} className="w-[230px]" />
        </SearchField>
        <SearchField label="유닛명">
          <SearchableSelect options={units} value={unitCode} onChange={setUnitCode} className="w-[260px]" />
        </SearchField>
        <SearchField label="품번">
          <SearchableSelect options={parts} value={searchPartObjid} onChange={setSearchPartObjid} className="w-[230px]" />
        </SearchField>
      </SearchForm>

      <div className="relative border border-gray-200 rounded bg-white overflow-auto" style={{ maxHeight: "calc(100vh - 310px)" }}>
        {loading && (
          <div className="absolute inset-0 z-20 flex items-center justify-center bg-white/70 backdrop-blur-[1px]">
            <div className="flex flex-col items-center gap-3">
              <div className="w-12 h-12 border-4 border-gray-300 border-t-primary rounded-full animate-spin" />
              <span className="text-sm font-semibold text-gray-700">Loading...</span>
            </div>
          </div>
        )}
        <table className="text-xs table-fixed border-collapse" style={{ width: 2295 }}>
          <colgroup>
            <col style={{ width: 100 }} />
            <col style={{ width: 200 }} />
            <col style={{ width: 125 }} />
            <col style={{ width: 125 }} />
            <col style={{ width: 270 }} />
            <col style={{ width: 60 }} />
            <col style={{ width: 45 }} />
            <col style={{ width: 45 }} />
            <col style={{ width: 55 }} />
            <col style={{ width: 110 }} />
            <col style={{ width: 110 }} />
            <col style={{ width: 110 }} />
            <col style={{ width: 100 }} />
            <col style={{ width: 100 }} />
            <col style={{ width: 90 }} />
            <col style={{ width: 90 }} />
            <col style={{ width: 90 }} />
            <col style={{ width: 90 }} />
            <col style={{ width: 80 }} />
            <col style={{ width: 90 }} />
            <col style={{ width: 90 }} />
            <col style={{ width: 120 }} />
          </colgroup>
          <thead>
            <tr>
              <th className={normalHeader} style={freezeHeader(0)}>프로젝트번호</th>
              <th className={normalHeader} style={freezeHeader(100)}>유닛명</th>
              <th className={normalHeader} style={freezeHeader(300)}>모품번</th>
              <th className={normalHeader} style={freezeHeader(425)}>품번</th>
              <th className={normalHeader} style={freezeHeader(550)}>품명</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>수량</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>3D</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>2D</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>PDF</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>EO구분</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>EO사유</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>PART구분</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>재질</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>사양(규격)</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>후처리</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>MAKER</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>대분류</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>중분류</th>
              <th className={normalHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>Revision</th>
              <th className={normalHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>EO No</th>
              <th className={normalHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>EO Date</th>
              <th className={yellowHeader} style={{ position: "sticky", top: 0, zIndex: 10, backgroundColor: "#F9FAFB" }}>비고</th>
            </tr>
          </thead>
          <tbody>
            {data.length === 0 ? (
              <tr><td colSpan={22} className="text-center py-10 text-gray-400">데이터가 없습니다.</td></tr>
            ) : data.map((row, idx) => {
              const editable = isEditable(idx);
              const frozenCell = "px-2 py-1 border border-gray-200";
              return (
                <tr key={idx}>
                  <td className={frozenCell} style={freezeCell(0)}>{String(row.PROJECT_NO ?? "")}</td>
                  <td className={frozenCell} style={freezeCell(100)}>{String(row.UNIT_NAME ?? "")}</td>
                  <td className={frozenCell} style={freezeCell(300)}>{String(row.PARENT_PART_INFO ?? "")}</td>
                  <td className={frozenCell} style={freezeCell(425)}>
                    <a className="text-primary hover:underline cursor-pointer" onClick={() => openPartForm(String(row.OBJID))}>
                      {String(row.PART_NO ?? "")}
                    </a>
                  </td>
                  <td className={frozenCell} style={freezeCell(550)}>{String(row.PART_NAME ?? "")}</td>
                  <td className="px-2 py-1 border border-gray-200 text-center">
                    {editable ? (
                      <input type="number" value={String(row.Q_QTY ?? "")} onChange={(e) => updateCell(idx, "Q_QTY", e.target.value)}
                        className="w-full h-6 text-xs border border-gray-300 rounded px-1 text-right" />
                    ) : String(row.Q_QTY ?? "")}
                  </td>
                  <td className="px-2 py-1 border border-gray-200 text-center">
                    <FolderCell count={row.CU01_CNT} onClick={() => openFilePopup(String(row.OBJID), "3D_CAD", "3D CAD 첨부파일")} />
                  </td>
                  <td className="px-2 py-1 border border-gray-200 text-center">
                    <FolderCell count={row.CU02_CNT} onClick={() => openFilePopup(String(row.OBJID), "2D_DRAWING_CAD", "2D(Drawing) CAD 첨부파일")} />
                  </td>
                  <td className="px-2 py-1 border border-gray-200 text-center">
                    <FolderCell count={row.CU03_CNT} onClick={() => openFilePopup(String(row.OBJID), "2D_PDF_CAD", "2D(PDF) CAD 첨부파일")} />
                  </td>
                  <td className="px-1 py-1 border border-gray-200">{codeSel(changeTypes, String(row.CHANGE_TYPE ?? ""), (v) => updateCell(idx, "CHANGE_TYPE", v), !editable)}</td>
                  <td className="px-1 py-1 border border-gray-200">{codeSel(changeOptions, String(row.CHANGE_OPTION ?? ""), (v) => updateCell(idx, "CHANGE_OPTION", v), !editable)}</td>
                  <td className="px-1 py-1 border border-gray-200">{codeSel(partTypes, String(row.PART_TYPE ?? ""), (v) => updateCell(idx, "PART_TYPE", v), !editable)}</td>
                  <td className="px-1 py-1 border border-gray-200">
                    <Input value={String(row.MATERIAL ?? "")} onChange={(e) => updateCell(idx, "MATERIAL", e.target.value)} disabled={!editable} className="h-6 text-xs" />
                  </td>
                  <td className="px-1 py-1 border border-gray-200">
                    <Input value={String(row.SPEC ?? "")} onChange={(e) => updateCell(idx, "SPEC", e.target.value)} disabled={!editable} className="h-6 text-xs" />
                  </td>
                  <td className="px-1 py-1 border border-gray-200">
                    <Input value={String(row.POST_PROCESSING ?? "")} onChange={(e) => updateCell(idx, "POST_PROCESSING", e.target.value)} disabled={!editable} className="h-6 text-xs" />
                  </td>
                  <td className="px-1 py-1 border border-gray-200">
                    <Input value={String(row.MAKER ?? "")} onChange={(e) => updateCell(idx, "MAKER", e.target.value)} disabled={!editable} className="h-6 text-xs" />
                  </td>
                  <td className="px-1 py-1 border border-gray-200">
                    <Input value={String(row.MAJOR_CATEGORY ?? "")} onChange={(e) => updateCell(idx, "MAJOR_CATEGORY", e.target.value)} disabled={!editable} className="h-6 text-xs" />
                  </td>
                  <td className="px-1 py-1 border border-gray-200">
                    <Input value={String(row.SUB_CATEGORY ?? "")} onChange={(e) => updateCell(idx, "SUB_CATEGORY", e.target.value)} disabled={!editable} className="h-6 text-xs" />
                  </td>
                  <td className="px-2 py-1 border border-gray-200 text-center">{String(row.REVISION ?? "")}</td>
                  <td className="px-2 py-1 border border-gray-200 text-center">{String(row.EO_NO ?? "")}</td>
                  <td className="px-2 py-1 border border-gray-200 text-center">{String(row.EO_DATE ?? "")}</td>
                  <td className="px-1 py-1 border border-gray-200">
                    <Input value={String(row.REMARK ?? "")} onChange={(e) => updateCell(idx, "REMARK", e.target.value)} disabled={!editable} className="h-6 text-xs" />
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}
