"use client";

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { ChevronRight, ChevronDown, Package, Layers, Box, AlertCircle } from "lucide-react";
import { cn } from "@/lib/utils";
import { entityJoinApi } from "@/lib/api/entityJoin";

/**
 * BOM 트리 노드 데이터
 */
interface BomTreeNode {
  id: string;
  bom_id: string;
  parent_detail_id: string | null;
  seq_no: string;
  level: string;
  child_item_id: string;
  child_item_code: string;
  child_item_name: string;
  child_item_type: string;
  quantity: string;
  unit: string;
  loss_rate: string;
  remark: string;
  children: BomTreeNode[];
}

/**
 * BOM 헤더 정보
 */
interface BomHeaderInfo {
  id: string;
  bom_number: string;
  item_code: string;
  item_name: string;
  item_type: string;
  base_qty: string;
  unit: string;
  version: string;
  revision: string;
  status: string;
  effective_date: string;
  expired_date: string;
  remark: string;
}

interface BomTreeComponentProps {
  component?: any;
  formData?: Record<string, any>;
  tableName?: string;
  companyCode?: string;
  isDesignMode?: boolean;
  selectedRowsData?: any[];
  [key: string]: any;
}

/**
 * BOM 트리 컴포넌트
 * 좌측 패널에서 BOM 헤더 선택 시 계층 구조로 BOM 디테일을 표시
 */
export function BomTreeComponent({
  component,
  formData,
  companyCode,
  isDesignMode = false,
  selectedRowsData,
  ...props
}: BomTreeComponentProps) {
  const [headerInfo, setHeaderInfo] = useState<BomHeaderInfo | null>(null);
  const [treeData, setTreeData] = useState<BomTreeNode[]>([]);
  const [expandedNodes, setExpandedNodes] = useState<Set<string>>(new Set());
  const [loading, setLoading] = useState(false);
  const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null);

  const config = component?.componentConfig || {};

  // 선택된 BOM 헤더에서 bom_id 추출
  const selectedBomId = useMemo(() => {
    // SplitPanel에서 좌측 선택 시 formData나 selectedRowsData로 전달됨
    if (selectedRowsData && selectedRowsData.length > 0) {
      return selectedRowsData[0]?.id;
    }
    if (formData?.id) return formData.id;
    return null;
  }, [formData, selectedRowsData]);

  // 선택된 BOM 헤더 정보 추출 (조인 필드명 매핑 포함)
  const selectedHeaderData = useMemo(() => {
    const raw = selectedRowsData?.[0] || (formData?.id ? formData : null);
    if (!raw) return null;
    return {
      ...raw,
      item_name: raw.item_id_item_name || raw.item_name || "",
      item_code: raw.item_id_item_number || raw.item_code || "",
      item_type: raw.item_id_division || raw.item_id_type || raw.item_type || "",
    } as BomHeaderInfo;
  }, [formData, selectedRowsData]);

  // BOM 디테일 데이터 로드
  const detailTable = config.detailTable || "bom_detail";
  const foreignKey = config.foreignKey || "bom_id";
  const sourceFk = "child_item_id";

  const loadBomDetails = useCallback(async (bomId: string) => {
    if (!bomId) return;
    setLoading(true);
    try {
      const result = await entityJoinApi.getTableDataWithJoins(detailTable, {
        page: 1,
        size: 500,
        search: { [foreignKey]: bomId },
        sortBy: "seq_no",
        sortOrder: "asc",
        enableEntityJoin: true,
      });

      const rows = (result.data || []).map((row: Record<string, any>) => {
        const mapped = { ...row };
        // 엔티티 조인 필드 매핑: child_item_id_item_name → child_item_name 등
        mapped.child_item_name = row[`${sourceFk}_item_name`] || row.child_item_name || "";
        mapped.child_item_code = row[`${sourceFk}_item_number`] || row.child_item_code || "";
        mapped.child_item_type = row[`${sourceFk}_type`] || row[`${sourceFk}_division`] || row.child_item_type || "";
        return mapped;
      });

      const tree = buildTree(rows);
      setTreeData(tree);
      const firstLevelIds = new Set<string>(tree.map((n: BomTreeNode) => n.id));
      setExpandedNodes(firstLevelIds);
    } catch (error) {
      console.error("[BomTree] 데이터 로드 실패:", error);
    } finally {
      setLoading(false);
    }
  }, [detailTable, foreignKey]);

  // 평면 데이터 -> 트리 구조 변환
  const buildTree = (flatData: any[]): BomTreeNode[] => {
    const nodeMap = new Map<string, BomTreeNode>();
    const roots: BomTreeNode[] = [];

    // 모든 노드를 맵에 등록
    flatData.forEach((item) => {
      nodeMap.set(item.id, { ...item, children: [] });
    });

    // 부모-자식 관계 설정
    flatData.forEach((item) => {
      const node = nodeMap.get(item.id)!;
      if (item.parent_detail_id && nodeMap.has(item.parent_detail_id)) {
        nodeMap.get(item.parent_detail_id)!.children.push(node);
      } else {
        roots.push(node);
      }
    });

    return roots;
  };

  // 선택된 BOM 변경 시 데이터 로드
  useEffect(() => {
    if (selectedBomId) {
      setHeaderInfo(selectedHeaderData);
      loadBomDetails(selectedBomId);
    } else {
      setHeaderInfo(null);
      setTreeData([]);
    }
  }, [selectedBomId, selectedHeaderData, loadBomDetails]);

  // 노드 펼치기/접기 토글
  const toggleNode = useCallback((nodeId: string) => {
    setExpandedNodes((prev) => {
      const next = new Set(prev);
      if (next.has(nodeId)) {
        next.delete(nodeId);
      } else {
        next.add(nodeId);
      }
      return next;
    });
  }, []);

  // 전체 펼치기
  const expandAll = useCallback(() => {
    const allIds = new Set<string>();
    const collectIds = (nodes: BomTreeNode[]) => {
      nodes.forEach((n) => {
        allIds.add(n.id);
        if (n.children.length > 0) collectIds(n.children);
      });
    };
    collectIds(treeData);
    setExpandedNodes(allIds);
  }, [treeData]);

  // 전체 접기
  const collapseAll = useCallback(() => {
    setExpandedNodes(new Set());
  }, []);

  // 품목 구분 라벨
  const getItemTypeLabel = (type: string) => {
    switch (type) {
      case "product": return "제품";
      case "semi": return "반제품";
      case "material": return "원자재";
      case "part": return "부품";
      default: return type || "-";
    }
  };

  // 품목 구분 아이콘 & 색상
  const getItemTypeStyle = (type: string) => {
    switch (type) {
      case "product":
        return { icon: Package, color: "text-blue-600", bg: "bg-blue-50" };
      case "semi":
        return { icon: Layers, color: "text-amber-600", bg: "bg-amber-50" };
      case "material":
        return { icon: Box, color: "text-emerald-600", bg: "bg-emerald-50" };
      default:
        return { icon: Box, color: "text-gray-500", bg: "bg-gray-50" };
    }
  };

  // 디자인 모드 미리보기
  if (isDesignMode) {
    return (
      <div className="flex h-full flex-col rounded-md border bg-white p-4">
        <div className="mb-3 flex items-center gap-2">
          <Layers className="h-4 w-4 text-primary" />
          <span className="text-sm font-medium">BOM 트리 뷰</span>
        </div>
        <div className="flex-1 space-y-1 rounded border border-dashed border-gray-300 p-3">
          <div className="flex items-center gap-2 text-xs text-gray-500">
            <ChevronDown className="h-3 w-3" />
            <Package className="h-3 w-3 text-blue-500" />
            <span>완제품 A (제품)</span>
            <span className="ml-auto text-gray-400">수량: 1</span>
          </div>
          <div className="ml-5 flex items-center gap-2 text-xs text-gray-500">
            <ChevronRight className="h-3 w-3" />
            <Layers className="h-3 w-3 text-amber-500" />
            <span>반제품 B (반제품)</span>
            <span className="ml-auto text-gray-400">수량: 2</span>
          </div>
          <div className="ml-5 flex items-center gap-2 text-xs text-gray-500">
            <span className="ml-3.5" />
            <Box className="h-3 w-3 text-emerald-500" />
            <span>원자재 C (원자재)</span>
            <span className="ml-auto text-gray-400">수량: 5</span>
          </div>
        </div>
      </div>
    );
  }

  // 선택 안 된 상태
  if (!selectedBomId) {
    return (
      <div className="flex h-full items-center justify-center">
        <div className="text-muted-foreground text-center text-sm">
          <p className="mb-2">좌측에서 BOM을 선택하세요</p>
          <p className="text-xs">선택한 BOM의 구성 정보가 트리로 표시됩니다</p>
        </div>
      </div>
    );
  }

  return (
    <div className="flex h-full flex-col">
      {/* 헤더 정보 */}
      {headerInfo && (
        <div className="border-b bg-gray-50/80 px-4 py-3">
          <div className="mb-2 flex items-center gap-2">
            <Package className="h-4 w-4 text-primary" />
            <h3 className="text-sm font-semibold">{headerInfo.item_name || "-"}</h3>
            <span className="rounded bg-primary/10 px-1.5 py-0.5 text-[10px] font-medium text-primary">
              {headerInfo.bom_number || "-"}
            </span>
            <span className={cn(
              "ml-1 rounded px-1.5 py-0.5 text-[10px] font-medium",
              headerInfo.status === "active" ? "bg-emerald-100 text-emerald-700" : "bg-gray-100 text-gray-500"
            )}>
              {headerInfo.status === "active" ? "사용" : "미사용"}
            </span>
          </div>
          <div className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted-foreground">
            <span>품목코드: <b className="text-foreground">{headerInfo.item_code || "-"}</b></span>
            <span>구분: <b className="text-foreground">{getItemTypeLabel(headerInfo.item_type)}</b></span>
            <span>기준수량: <b className="text-foreground">{headerInfo.base_qty || "1"} {headerInfo.unit || ""}</b></span>
            <span>버전: <b className="text-foreground">v{headerInfo.version || "1.0"} (차수 {headerInfo.revision || "1"})</b></span>
          </div>
        </div>
      )}

      {/* 트리 툴바 */}
      <div className="flex items-center gap-2 border-b px-4 py-2">
        <span className="text-xs font-medium text-muted-foreground">BOM 구성</span>
        <span className="rounded-full bg-primary/10 px-1.5 py-0.5 text-[10px] font-medium text-primary">
          {treeData.length}건
        </span>
        <div className="ml-auto flex gap-1">
          <button
            onClick={expandAll}
            className="rounded px-2 py-0.5 text-[10px] text-muted-foreground hover:bg-gray-100"
          >
            전체 펼치기
          </button>
          <button
            onClick={collapseAll}
            className="rounded px-2 py-0.5 text-[10px] text-muted-foreground hover:bg-gray-100"
          >
            전체 접기
          </button>
        </div>
      </div>

      {/* 트리 컨텐츠 */}
      <div className="flex-1 overflow-auto px-2 py-2">
        {loading ? (
          <div className="flex h-32 items-center justify-center">
            <div className="text-muted-foreground text-sm">로딩 중...</div>
          </div>
        ) : treeData.length === 0 ? (
          <div className="flex h-32 flex-col items-center justify-center gap-2">
            <AlertCircle className="h-5 w-5 text-muted-foreground" />
            <p className="text-xs text-muted-foreground">등록된 하위 품목이 없습니다</p>
          </div>
        ) : (
          <div className="space-y-0.5">
            {treeData.map((node) => (
              <TreeNodeRow
                key={node.id}
                node={node}
                depth={0}
                expandedNodes={expandedNodes}
                selectedNodeId={selectedNodeId}
                onToggle={toggleNode}
                onSelect={setSelectedNodeId}
                getItemTypeLabel={getItemTypeLabel}
                getItemTypeStyle={getItemTypeStyle}
              />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

/**
 * 트리 노드 행 (재귀 렌더링)
 */
interface TreeNodeRowProps {
  node: BomTreeNode;
  depth: number;
  expandedNodes: Set<string>;
  selectedNodeId: string | null;
  onToggle: (id: string) => void;
  onSelect: (id: string) => void;
  getItemTypeLabel: (type: string) => string;
  getItemTypeStyle: (type: string) => { icon: any; color: string; bg: string };
}

function TreeNodeRow({
  node,
  depth,
  expandedNodes,
  selectedNodeId,
  onToggle,
  onSelect,
  getItemTypeLabel,
  getItemTypeStyle,
}: TreeNodeRowProps) {
  const isExpanded = expandedNodes.has(node.id);
  const hasChildren = node.children.length > 0;
  const isSelected = selectedNodeId === node.id;
  const style = getItemTypeStyle(node.child_item_type);
  const ItemIcon = style.icon;

  return (
    <>
      <div
        className={cn(
          "group flex cursor-pointer items-center gap-1.5 rounded-md px-2 py-1.5 transition-colors",
          isSelected ? "bg-primary/10" : "hover:bg-gray-50"
        )}
        style={{ paddingLeft: `${depth * 20 + 8}px` }}
        onClick={() => {
          onSelect(node.id);
          if (hasChildren) onToggle(node.id);
        }}
      >
        {/* 펼치기/접기 화살표 */}
        <span className="flex h-4 w-4 flex-shrink-0 items-center justify-center">
          {hasChildren ? (
            isExpanded ? (
              <ChevronDown className="h-3.5 w-3.5 text-gray-400" />
            ) : (
              <ChevronRight className="h-3.5 w-3.5 text-gray-400" />
            )
          ) : (
            <span className="h-1 w-1 rounded-full bg-gray-300" />
          )}
        </span>

        {/* 품목 타입 아이콘 */}
        <span className={cn("flex h-5 w-5 flex-shrink-0 items-center justify-center rounded", style.bg)}>
          <ItemIcon className={cn("h-3 w-3", style.color)} />
        </span>

        {/* 품목 정보 */}
        <div className="flex min-w-0 flex-1 items-center gap-2">
          <span className="truncate text-xs font-medium text-foreground">
            {node.child_item_name || "-"}
          </span>
          <span className="flex-shrink-0 text-[10px] text-muted-foreground">
            {node.child_item_code || ""}
          </span>
          <span className={cn(
            "flex-shrink-0 rounded px-1 py-0.5 text-[10px]",
            style.bg, style.color
          )}>
            {getItemTypeLabel(node.child_item_type)}
          </span>
        </div>

        {/* 수량/단위 */}
        <div className="flex flex-shrink-0 items-center gap-2 text-[11px]">
          <span className="text-muted-foreground">
            수량: <b className="text-foreground">{node.quantity || "0"}</b> {node.unit || ""}
          </span>
          {node.loss_rate && node.loss_rate !== "0" && (
            <span className="text-amber-600">
              로스: {node.loss_rate}%
            </span>
          )}
        </div>
      </div>

      {/* 하위 노드 재귀 렌더링 */}
      {hasChildren && isExpanded && (
        <div>
          {node.children.map((child) => (
            <TreeNodeRow
              key={child.id}
              node={child}
              depth={depth + 1}
              expandedNodes={expandedNodes}
              selectedNodeId={selectedNodeId}
              onToggle={onToggle}
              onSelect={onSelect}
              getItemTypeLabel={getItemTypeLabel}
              getItemTypeStyle={getItemTypeStyle}
            />
          ))}
        </div>
      )}
    </>
  );
}
