"use client";

// 생산관리 > M-BOM 관리 — wace productionplanning/mBomMgmtList.jsp 1:1
// 그리드: PROJECT_MGMT × CONTRACT_ITEM 펼침 (1 프로젝트 = 1+ 행) + M-BOM 상태/저장일
// 검색: 주문유형 / 제품구분 / 국내해외 / 고객사 / 유무상 / S/N / 품번 / 품명 / 접수일 / 요청납기
// 액션:
//   PR-A1: 조회 / 초기화 / 페이지
//   PR-A2: 행 더블클릭 → MbomDetailDialog (헤더 + read-only 트리 4분기)
//   PR-B3: [구매리스트 생성] 버튼 — wace fn_openPurchaseListPopup 1:1 (단건 체크 + 1:1 강제)

import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { ShoppingCart, Loader2, Copy } from "lucide-react";
import { toast } from "sonner";
import { DataGrid, DataGridColumn } from "@/components/common/DataGrid";
import { SmartSelect, SmartSelectOption } from "@/components/common/SmartSelect";
import { CustomerSelect } from "@/components/common/CustomerSelect";
import { CompactFilterBar, CompactFilterField, CompactDateRange } from "@/components/common/CompactFilterBar";
import { PageHeader } from "@/components/common/PageHeader";
import { useConfirmDialog } from "@/components/common/ConfirmDialog";
import { apiClient } from "@/lib/api/client";
import { mbomApi, MbomListFilter, MbomRow } from "@/lib/api/mbom";
import { MbomDetailDialog } from "@/components/production/MbomDetailDialog";
import { BomCopyDialog } from "@/components/production/BomCopyDialog";
import { exportToExcel } from "@/lib/utils/excelExport";

const PARENT_CATEGORY = "0000167"; // 주문유형 comm_code parent_code_id
const PARENT_PRODUCT  = "0000001"; // 제품구분 comm_code parent_code_id
const PARENT_PAID     = "0001782"; // 유/무상 (참고: 빈 결과여도 raw paid/free 매칭으로 fallback)

interface CodeOpt extends SmartSelectOption { sort?: number | null }

const AREA_OPTS: SmartSelectOption[] = [
  { code: "국내", label: "국내" },
  { code: "해외", label: "해외" },
];

// 운영판 1:1 — paid/free raw 매칭이 기본. comm_code 응답이 비어있을 때 사용.
const PAID_FALLBACK_OPTS: SmartSelectOption[] = [
  { code: "paid", label: "유상" },
  { code: "free", label: "무상" },
];

const EMPTY_FILTER: MbomListFilter = {
  search_category_cd: "",
  search_product_cd: "",
  search_area_cd: "",
  search_customer_objid: "",
  search_paid_type: "",
  search_serial_no: "",
  search_part_no: "",
  search_part_name: "",
  search_receipt_date_from: "",
  search_receipt_date_to: "",
  search_req_del_date_from: "",
  search_req_del_date_to: "",
  page: 1,
  page_size: 50,   // DataGrid 서버 페이지네이션 — 페이지 변경/사이즈 변경 시 부모가 직접 재요청
};

// 그리드 컬럼은 useMemo 로 컴포넌트 내부에서 생성 — onClick(openDialog) 캡처 위해.

export default function MbomMgmtPage() {
  const { confirm, ConfirmDialogComponent } = useConfirmDialog();
  const [rows, setRows] = useState<MbomRow[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(false);
  const [filter, setFilter] = useState<MbomListFilter>(EMPTY_FILTER);

  const [categoryOpts, setCategoryOpts] = useState<CodeOpt[]>([]);
  const [productOpts, setProductOpts]   = useState<CodeOpt[]>([]);
  const [paidOpts, setPaidOpts]         = useState<CodeOpt[]>([]);

  const [dialogOpen, setDialogOpen]       = useState(false);
  const [dialogObjid, setDialogObjid]     = useState<string | null>(null);

  // PR-B3: 구매리스트 생성 — 그리드 단건 체크 + 버튼 트리거 (wace 1:1)
  const [checkedIds, setCheckedIds] = useState<string[]>([]);
  const [creatingPurchaseList, setCreatingPurchaseList] = useState(false);

  // PR-B5+: BOM 복사 — 단건 체크 + 다이얼로그 (wace fn_openBomCopyPopup 1:1)
  const [bomCopyOpen, setBomCopyOpen] = useState(false);
  const [bomCopyTarget, setBomCopyTarget] = useState<{
    projectObjid: string;
    partNo: string;
    partName: string;
    productCode: string;
    hasMbom: boolean;
  } | null>(null);

  const fetchList = useCallback(async (override?: Partial<MbomListFilter>) => {
    setLoading(true);
    try {
      const f = { ...filter, ...override };
      const res = await mbomApi.list(f);
      setRows(res.rows ?? []);
      setTotal(res.totalCount ?? 0);
    } catch (e: any) {
      toast.error(e?.response?.data?.message ?? e?.message ?? "조회 실패");
    } finally {
      setLoading(false);
    }
  }, [filter]);

  // 초기 옵션 + 첫 조회
  useEffect(() => {
    let dead = false;
    (async () => {
      try {
        const [c1, c2, c3] = await Promise.all([
          apiClient.get(`/sales/codes/${PARENT_CATEGORY}`),
          apiClient.get(`/sales/codes/${PARENT_PRODUCT}`),
          apiClient.get(`/sales/codes/${PARENT_PAID}`),
        ]);
        if (dead) return;
        setCategoryOpts(c1.data?.data ?? []);
        setProductOpts(c2.data?.data ?? []);
        setPaidOpts(c3.data?.data ?? []);
      } catch {
        /* 옵션 로드 실패는 무시 — 그리드는 조회 가능 */
      }
    })();
    fetchList(EMPTY_FILTER);
    return () => { dead = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // DataGrid 키 부여 (objid + part_no 조합 — 같은 프로젝트 다중 행 unique)
  // mbom_has: folder 컬럼이 숫자 > 0 일 때 파랑. mbom_header_objid 가 있으면 저장된 M-BOM.
  const gridRows = useMemo(
    () => rows.map((r, i) => ({
      ...r,
      id: `${r.objid}__${r.part_no ?? ""}__${i}`,
      mbom_has: r.mbom_header_objid ? 1 : 0,
    })),
    [rows]
  );

  const openMbomDialog = useCallback((row: any) => {
    if (!row?.objid) return;
    setDialogObjid(String(row.objid));
    setDialogOpen(true);
  }, []);

  const GRID_COLUMNS: DataGridColumn[] = useMemo(() => ([
    { key: "project_no",       label: "프로젝트번호",   width: "w-[140px]" },
    { key: "category_name",    label: "주문유형",       width: "w-[115px]", align: "center" },
    { key: "product_name",     label: "제품구분",       width: "w-[115px]", align: "center" },
    { key: "area_name",        label: "국내/해외",      width: "w-[115px]", align: "center" },
    { key: "receipt_date",     label: "접수일",         width: "w-[115px]", align: "center" },
    { key: "writer_name",      label: "작성자",         width: "w-[115px]", align: "center" },
    { key: "customer_name",    label: "고객사",         minWidth: "min-w-[160px]" },
    { key: "paid_type_name",   label: "유/무상",        width: "w-[100px]", align: "center" },
    { key: "part_no",          label: "품번",           width: "w-[150px]" },
    { key: "part_name",        label: "품명",           minWidth: "min-w-[180px]" },
    { key: "serial_no",        label: "S/N",            width: "w-[115px]", align: "center" },
    { key: "quantity",         label: "수주수량",       width: "w-[115px]", align: "right", formatNumber: true },
    { key: "req_del_date",     label: "요청납기",       width: "w-[115px]", align: "center" },
    { key: "customer_request", label: "고객사요청사항", minWidth: "min-w-[200px]" },
    // M-BOM 컬럼 — 폴더 아이콘 (저장됨=파랑, 미저장=흰색). 클릭 시 본 편집 다이얼로그.
    { key: "mbom_has",         label: "M-BOM",          width: "w-[100px]", align: "center",
      renderType: "folder",   onClick: openMbomDialog },
    { key: "mbom_regdate",     label: "최종저장일",     width: "w-[125px]", align: "center" },
  ]), [openMbomDialog]);

  // ─── 하단 통계 ──────────────────────────────────────────────
  // 전체 건수(서버 total) / 현재 페이지 건수 / 수주수량 합계(페이지) / M-BOM 저장 비율(페이지)
  const mbomSummary = useMemo(() => {
    const pageCount = gridRows.length;
    const qtySum    = gridRows.reduce((acc, r: any) => acc + Number(r.quantity || 0), 0);
    const hasMbom   = gridRows.reduce((acc, r: any) => acc + (Number(r.mbom_has || 0) > 0 ? 1 : 0), 0);
    const rate      = pageCount === 0 ? 0 : (hasMbom / pageCount) * 100;
    const intFmt = (n: number) => n.toLocaleString();
    return [
      { label: "전체 건수", value: intFmt(total), suffix: "건" },
      { label: "페이지 건수", value: intFmt(pageCount), suffix: "건" },
      { label: "수주수량 합계", value: intFmt(qtySum) },
      { label: "M-BOM 저장", value: `${intFmt(hasMbom)} / ${intFmt(pageCount)}`, suffix: `(${rate.toFixed(1)}%)` },
    ];
  }, [gridRows, total]);

  const handleSearch = () => {
    setFilter((f) => ({ ...f, page: 1 }));
    fetchList({ page: 1 });
  };

  const handleReset = () => {
    setFilter(EMPTY_FILTER);
    fetchList(EMPTY_FILTER);
  };

  // PR-B3 — 구매리스트 생성 (wace fn_openPurchaseListPopup 1:1)
  // 검증 순서: 1행 선택 → MBOM_HEADER_OBJID 존재 → PURCHASE_LIST_OBJID 없음 → confirm → POST
  const handleCreatePurchaseList = useCallback(async () => {
    if (checkedIds.length === 0) {
      toast.info("구매리스트를 생성할 프로젝트를 선택해주세요.");
      return;
    }
    if (checkedIds.length > 1) {
      toast.info("한 번에 하나의 프로젝트만 선택해주세요.");
      return;
    }
    const row = gridRows.find((r: any) => r.id === checkedIds[0]) as any;
    if (!row?.objid) {
      toast.error("프로젝트 OBJID를 찾을 수 없습니다.");
      return;
    }
    if (!row.mbom_header_objid) {
      toast.warning("M-BOM이 생성되지 않았습니다.\n먼저 M-BOM을 생성해주세요.");
      return;
    }
    if (row.purchase_list_objid) {
      toast.info("이미 생성된 구매리스트가 있습니다.\n구매리스트관리 화면에서 확인하세요.");
      return;
    }
    const ok = await confirm("구매리스트를 생성하시겠어요?", {
      description: `프로젝트 ${row.project_no ?? ""} 의 M-BOM 으로 구매리스트(SALES_REQUEST)를 생성합니다.`,
      confirmText: "생성",
    });
    if (!ok) return;
    setCreatingPurchaseList(true);
    try {
      const res = await mbomApi.createSalesRequest({
        mbom_header_objid: String(row.mbom_header_objid),
        project_mgmt_objid: String(row.objid),
      });
      toast.success(`구매리스트가 생성되었어요. (${res.request_mng_no})`);
      setCheckedIds([]);
      fetchList();
    } catch (e: any) {
      toast.error(e?.response?.data?.message ?? e?.message ?? "구매리스트 생성 실패");
    } finally {
      setCreatingPurchaseList(false);
    }
  }, [checkedIds, gridRows, confirm, fetchList]);

  // PR-B5+ — BOM 복사 (wace fn_openBomCopyPopup 1:1)
  // 검증: 단건 체크 + objid 확인. M-BOM 이미 있으면 다이얼로그 내부에서 "초기화" 경고.
  const handleOpenBomCopy = useCallback(() => {
    if (checkedIds.length === 0) {
      toast.info("BOM 을 복사할 프로젝트를 선택해주세요.");
      return;
    }
    if (checkedIds.length > 1) {
      toast.info("한 번에 하나의 프로젝트만 선택해주세요.");
      return;
    }
    const row = gridRows.find((r: any) => r.id === checkedIds[0]) as any;
    if (!row?.objid) {
      toast.error("프로젝트 OBJID를 찾을 수 없습니다.");
      return;
    }
    setBomCopyTarget({
      projectObjid: String(row.objid),
      partNo: String(row.part_no ?? ""),
      partName: String(row.part_name ?? ""),
      productCode: String(row.product ?? ""),
      hasMbom: !!(row.mbom_header_objid && String(row.mbom_status ?? "") === "Y"),
    });
    setBomCopyOpen(true);
  }, [checkedIds, gridRows]);

  return (
    <div className="flex h-full flex-col overflow-hidden p-2 gap-2">
      <PageHeader
        loading={loading}
        onSearch={handleSearch}
        onReset={handleReset}
        actions={
          <>
            <Button
              size="sm"
              variant="outline"
              className="h-8 gap-1 px-2 text-xs"
              onClick={handleOpenBomCopy}
              disabled={checkedIds.length === 0}
            >
              <Copy className="h-3.5 w-3.5" />
              BOM 복사
            </Button>
            <Button
              size="sm"
              variant="default"
              className="h-8 gap-1 px-2 text-xs"
              onClick={handleCreatePurchaseList}
              disabled={creatingPurchaseList || checkedIds.length === 0}
            >
              {creatingPurchaseList
                ? <Loader2 className="h-3.5 w-3.5 animate-spin" />
                : <ShoppingCart className="h-3.5 w-3.5" />}
              구매리스트 생성
            </Button>
          </>
        }
      />
      <CompactFilterBar
        totalText={<>총 {total.toLocaleString()}건 · PROJECT_MGMT × CONTRACT_ITEM 펼침</>}
      >
        <CompactFilterField label="주문유형" width={130}>
          <SmartSelect
            options={categoryOpts}
            value={filter.search_category_cd ?? ""}
            onValueChange={(v) => setFilter({ ...filter, search_category_cd: v })}
          />
        </CompactFilterField>
        <CompactFilterField label="제품구분" width={130}>
          <SmartSelect
            options={productOpts}
            value={filter.search_product_cd ?? ""}
            onValueChange={(v) => setFilter({ ...filter, search_product_cd: v })}
          />
        </CompactFilterField>
        <CompactFilterField label="국내/해외" width={100}>
          <SmartSelect
            options={AREA_OPTS}
            value={filter.search_area_cd ?? ""}
            onValueChange={(v) => setFilter({ ...filter, search_area_cd: v })}
          />
        </CompactFilterField>
        <CompactFilterField label="고객사" width={160}>
          <CustomerSelect
            value={filter.search_customer_objid ?? ""}
            onValueChange={(v) => setFilter({ ...filter, search_customer_objid: v })}
          />
        </CompactFilterField>
        <CompactFilterField label="유/무상" width={110}>
          <SmartSelect
            options={paidOpts.length > 0 ? paidOpts : PAID_FALLBACK_OPTS}
            value={filter.search_paid_type ?? ""}
            onValueChange={(v) => setFilter({ ...filter, search_paid_type: v })}
          />
        </CompactFilterField>
        <CompactFilterField label="S/N" width={120}>
          <Input
            value={filter.search_serial_no ?? ""}
            onChange={(e) => setFilter({ ...filter, search_serial_no: e.target.value })}
          />
        </CompactFilterField>
        <CompactFilterField label="품번" width={130}>
          <Input
            value={filter.search_part_no ?? ""}
            onChange={(e) => setFilter({ ...filter, search_part_no: e.target.value })}
          />
        </CompactFilterField>
        <CompactFilterField label="품명" width={150}>
          <Input
            value={filter.search_part_name ?? ""}
            onChange={(e) => setFilter({ ...filter, search_part_name: e.target.value })}
          />
        </CompactFilterField>
        <CompactFilterField label="접수일" width={280}>
          <CompactDateRange
            from={filter.search_receipt_date_from ?? ""}
            setFrom={(v) => setFilter({ ...filter, search_receipt_date_from: v })}
            to={filter.search_receipt_date_to ?? ""}
            setTo={(v) => setFilter({ ...filter, search_receipt_date_to: v })}
          />
        </CompactFilterField>
        <CompactFilterField label="요청납기" width={280}>
          <CompactDateRange
            from={filter.search_req_del_date_from ?? ""}
            setFrom={(v) => setFilter({ ...filter, search_req_del_date_from: v })}
            to={filter.search_req_del_date_to ?? ""}
            setTo={(v) => setFilter({ ...filter, search_req_del_date_to: v })}
          />
        </CompactFilterField>
      </CompactFilterBar>

      <DataGrid
        columns={GRID_COLUMNS}
        data={gridRows}
        loading={loading}
        showRowNumber
        showCheckbox
        checkedIds={checkedIds}
        onCheckedChange={setCheckedIds}
        emptyMessage="조건에 맞는 프로젝트가 없습니다."
        gridId="production-mbom-mgmt"
        pageSizeOptions={[25, 50, 100, 200, 500]}
        paginationStyle="range"
        serverPaging
        serverPage={filter.page ?? 1}
        serverPageSize={filter.page_size ?? 50}
        serverTotalItems={total}
        onPageChange={(p) => { setFilter(f => ({ ...f, page: p })); fetchList({ page: p }); }}
        onPageSizeChange={(n) => { setFilter(f => ({ ...f, page: 1, page_size: n })); fetchList({ page: 1, page_size: n }); }}
        onRowDoubleClick={(row: any) => {
          if (!row?.objid) return;
          setDialogObjid(String(row.objid));
          setDialogOpen(true);
        }}
        showColumnSettings
        summaryStats={mbomSummary}
        systemColumnKeys={["writer_name", "mbom_regdate"]}
        onRefresh={() => fetchList()}
        onDownload={() => {
          if (gridRows.length === 0) { toast.info("내보낼 데이터가 없습니다."); return; }
          // 서버 페이지네이션 — 현재 페이지 행만 export. 전체 export 는 별 endpoint 필요시 추가.
          const exportRows = gridRows.map((r: any) => {
            const out: Record<string, any> = {};
            GRID_COLUMNS.forEach((col) => { out[col.label] = r[col.key] ?? ""; });
            return out;
          });
          exportToExcel(exportRows, "M-BOM_관리.xlsx", "M-BOM_관리");
        }}
        showChart
      />

      <MbomDetailDialog
        open={dialogOpen}
        onOpenChange={setDialogOpen}
        projectObjid={dialogObjid}
        onSaved={fetchList}
      />

      <BomCopyDialog
        open={bomCopyOpen}
        onOpenChange={(v) => {
          setBomCopyOpen(v);
          if (!v) setBomCopyTarget(null);
        }}
        projectObjid={bomCopyTarget?.projectObjid ?? null}
        partNo={bomCopyTarget?.partNo ?? null}
        partName={bomCopyTarget?.partName ?? null}
        productCode={bomCopyTarget?.productCode ?? null}
        hasMbom={bomCopyTarget?.hasMbom ?? false}
        onSaved={() => {
          setCheckedIds([]);
          fetchList();
        }}
      />

      {ConfirmDialogComponent}
    </div>
  );
}

