"use client";

import { getAdaptiveLabelColor } from "@/lib/utils/darkModeColor";

/**
 * V2Hierarchy
 *
 * 통합 계층 구조 컴포넌트
 * - tree: 트리 뷰
 * - org: 조직도
 * - bom: BOM 구조
 * - cascading: 연쇄 드롭다운
 */

import React, { forwardRef, useCallback, useState } from "react";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { cn } from "@/lib/utils";
import { V2HierarchyProps, HierarchyNode } from "@/types/v2-components";
import {
  ChevronRight,
  ChevronDown,
  Folder,
  FolderOpen,
  File,
  Plus,
  Minus,
  GripVertical,
  User,
  Users,
  Building,
} from "lucide-react";

/**
 * 트리 노드 컴포넌트
 */
const TreeNode = forwardRef<
  HTMLDivElement,
  {
    node: HierarchyNode;
    level: number;
    maxLevel?: number;
    selectedNode?: HierarchyNode;
    onSelect?: (node: HierarchyNode) => void;
    editable?: boolean;
    draggable?: boolean;
    showQty?: boolean;
    className?: string;
  }
>(({ node, level, maxLevel, selectedNode, onSelect, editable, draggable, showQty, className }, ref) => {
  const [isOpen, setIsOpen] = useState(level < 2);
  const hasChildren = node.children && node.children.length > 0;
  const isSelected = selectedNode?.id === node.id;

  // 최대 레벨 제한
  if (maxLevel && level >= maxLevel) {
    return null;
  }

  return (
    <div ref={ref} className={className}>
      <Collapsible open={isOpen} onOpenChange={setIsOpen}>
        <div
          className={cn(
            "hover:bg-muted/50 flex cursor-pointer items-center gap-1 rounded px-2 py-1",
            isSelected && "bg-primary/10 text-primary",
          )}
          style={{ paddingLeft: `${level * 16 + 8}px` }}
          onClick={() => onSelect?.(node)}
        >
          {/* 드래그 핸들 */}
          {draggable && <GripVertical className="text-muted-foreground h-4 w-4 cursor-grab" />}

          {/* 확장/축소 아이콘 */}
          {hasChildren ? (
            <CollapsibleTrigger asChild onClick={(e) => e.stopPropagation()}>
              <Button variant="ghost" size="icon" className="h-5 w-5 p-0">
                {isOpen ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
              </Button>
            </CollapsibleTrigger>
          ) : (
            <span className="w-5" />
          )}

          {/* 폴더/파일 아이콘 */}
          {hasChildren ? (
            isOpen ? (
              <FolderOpen className="h-4 w-4 text-amber-500" />
            ) : (
              <Folder className="h-4 w-4 text-amber-500" />
            )
          ) : (
            <File className="text-muted-foreground h-4 w-4" />
          )}

          {/* 라벨 */}
          <span className="flex-1 truncate text-sm">{node.label}</span>

          {/* 수량 (BOM용) */}
          {showQty && node.data?.qty && (
            <span className="text-muted-foreground bg-muted rounded px-1.5 py-0.5 text-xs">
              x{String(node.data.qty)}
            </span>
          )}

          {/* 편집 버튼 */}
          {editable && (
            <div className="flex gap-1">
              <Button
                variant="ghost"
                size="icon"
                className="h-5 w-5 p-0 opacity-0 group-hover:opacity-100"
                onClick={(e) => {
                  e.stopPropagation();
                }}
              >
                <Plus className="h-3 w-3" />
              </Button>
            </div>
          )}
        </div>

        {/* 자식 노드 */}
        {hasChildren && (
          <CollapsibleContent>
            {node.children!.map((child) => (
              <TreeNode
                key={child.id}
                node={child}
                level={level + 1}
                maxLevel={maxLevel}
                selectedNode={selectedNode}
                onSelect={onSelect}
                editable={editable}
                draggable={draggable}
                showQty={showQty}
              />
            ))}
          </CollapsibleContent>
        )}
      </Collapsible>
    </div>
  );
});
TreeNode.displayName = "TreeNode";

/**
 * 트리 뷰 컴포넌트
 */
const TreeView = forwardRef<
  HTMLDivElement,
  {
    data: HierarchyNode[];
    selectedNode?: HierarchyNode;
    onNodeSelect?: (node: HierarchyNode) => void;
    editable?: boolean;
    draggable?: boolean;
    maxLevel?: number;
    className?: string;
  }
>(({ data, selectedNode, onNodeSelect, editable, draggable, maxLevel, className }, ref) => {
  return (
    <div ref={ref} className={cn("rounded-lg border p-2", className)}>
      {data.length === 0 ? (
        <div className="text-muted-foreground py-8 text-center text-sm">데이터가 없습니다</div>
      ) : (
        data.map((node) => (
          <TreeNode
            key={node.id}
            node={node}
            level={0}
            maxLevel={maxLevel}
            selectedNode={selectedNode}
            onSelect={onNodeSelect}
            editable={editable}
            draggable={draggable}
          />
        ))
      )}
    </div>
  );
});
TreeView.displayName = "TreeView";

/**
 * 조직도 뷰 컴포넌트
 */
const OrgView = forwardRef<
  HTMLDivElement,
  {
    data: HierarchyNode[];
    selectedNode?: HierarchyNode;
    onNodeSelect?: (node: HierarchyNode) => void;
    className?: string;
  }
>(({ data, selectedNode, onNodeSelect, className }, ref) => {
  const renderOrgNode = (node: HierarchyNode, isRoot = false) => {
    const isSelected = selectedNode?.id === node.id;
    const hasChildren = node.children && node.children.length > 0;

    return (
      <div key={node.id} className="flex flex-col items-center">
        {/* 노드 카드 */}
        <div
          className={cn(
            "hover:border-primary flex cursor-pointer flex-col items-center rounded-lg border p-3 transition-colors",
            isSelected && "border-primary bg-primary/5",
            isRoot && "bg-primary/10",
          )}
          onClick={() => onNodeSelect?.(node)}
        >
          <div
            className={cn(
              "mb-2 flex h-10 w-10 items-center justify-center rounded-full",
              isRoot ? "bg-primary text-primary-foreground" : "bg-muted",
            )}
          >
            {isRoot ? (
              <Building className="h-5 w-5" />
            ) : hasChildren ? (
              <Users className="h-5 w-5" />
            ) : (
              <User className="h-5 w-5" />
            )}
          </div>
          <div className="text-center">
            <div className="text-sm font-medium">{node.label}</div>
            {node.data?.title && <div className="text-muted-foreground text-xs">{String(node.data.title)}</div>}
          </div>
        </div>

        {/* 자식 노드 */}
        {hasChildren && (
          <>
            {/* 연결선 */}
            <div className="bg-border h-4 w-px" />
            <div className="flex gap-4">
              {node.children!.map((child, index) => (
                <React.Fragment key={child.id}>
                  {index > 0 && <div className="w-4" />}
                  {renderOrgNode(child)}
                </React.Fragment>
              ))}
            </div>
          </>
        )}
      </div>
    );
  };

  return (
    <div ref={ref} className={cn("overflow-auto p-4", className)}>
      {data.length === 0 ? (
        <div className="text-muted-foreground py-8 text-center text-sm">조직 데이터가 없습니다</div>
      ) : (
        <div className="flex flex-col items-center gap-4">{data.map((node) => renderOrgNode(node, true))}</div>
      )}
    </div>
  );
});
OrgView.displayName = "OrgView";

/**
 * BOM 뷰 컴포넌트 (수량 포함 트리)
 */
const BomView = forwardRef<
  HTMLDivElement,
  {
    data: HierarchyNode[];
    selectedNode?: HierarchyNode;
    onNodeSelect?: (node: HierarchyNode) => void;
    editable?: boolean;
    className?: string;
  }
>(({ data, selectedNode, onNodeSelect, editable, className }, ref) => {
  return (
    <div ref={ref} className={cn("rounded-lg border p-2", className)}>
      {data.length === 0 ? (
        <div className="text-muted-foreground py-8 text-center text-sm">BOM 데이터가 없습니다</div>
      ) : (
        data.map((node) => (
          <TreeNode
            key={node.id}
            node={node}
            level={0}
            selectedNode={selectedNode}
            onSelect={onNodeSelect}
            editable={editable}
            showQty={true}
          />
        ))
      )}
    </div>
  );
});
BomView.displayName = "BomView";

/**
 * 연쇄 드롭다운 컴포넌트
 */
const CascadingView = forwardRef<
  HTMLDivElement,
  {
    data: HierarchyNode[];
    selectedNode?: HierarchyNode;
    onNodeSelect?: (node: HierarchyNode) => void;
    maxLevel?: number;
    className?: string;
  }
>(({ data, selectedNode, onNodeSelect, maxLevel = 3, className }, ref) => {
  const [selections, setSelections] = useState<string[]>([]);

  // 레벨별 옵션 가져오기
  const getOptionsForLevel = (level: number): HierarchyNode[] => {
    if (level === 0) return data;

    let currentNodes = data;
    for (let i = 0; i < level; i++) {
      const selectedId = selections[i];
      if (!selectedId) return [];

      const selectedNode = currentNodes.find((n) => n.id === selectedId);
      if (!selectedNode?.children) return [];

      currentNodes = selectedNode.children;
    }
    return currentNodes;
  };

  // 선택 핸들러
  const handleSelect = (level: number, nodeId: string) => {
    const newSelections = [...selections.slice(0, level), nodeId];
    setSelections(newSelections);

    // 마지막 선택된 노드 찾기
    let node = data.find((n) => n.id === newSelections[0]);
    for (let i = 1; i < newSelections.length; i++) {
      node = node?.children?.find((n) => n.id === newSelections[i]);
    }
    if (node) {
      onNodeSelect?.(node);
    }
  };

  return (
    <div ref={ref} className={cn("flex gap-2", className)}>
      {Array.from({ length: maxLevel }, (_, level) => {
        const options = getOptionsForLevel(level);
        const isDisabled = level > 0 && !selections[level - 1];

        return (
          <Select
            key={level}
            value={selections[level] || ""}
            onValueChange={(value) => handleSelect(level, value)}
            disabled={isDisabled || options.length === 0}
          >
            <SelectTrigger className="flex-1">
              <SelectValue placeholder={`${level + 1}단계 선택`} />
            </SelectTrigger>
            <SelectContent>
              {options.map((option) => (
                <SelectItem key={option.id} value={option.id}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        );
      })}
    </div>
  );
});
CascadingView.displayName = "CascadingView";

/**
 * 메인 V2Hierarchy 컴포넌트
 */
export const V2Hierarchy = forwardRef<HTMLDivElement, V2HierarchyProps>((props, ref) => {
  const { id, label, required, style, size, config: configProp, data = [], selectedNode, onNodeSelect } = props;

  // config가 없으면 기본값 사용
  const config = configProp || { type: "tree" as const, viewMode: "tree" as const, dataSource: "static" as const };

  // 뷰모드별 렌더링
  const renderHierarchy = () => {
    const viewMode = config.viewMode || config.type || "tree";
    switch (viewMode) {
      case "tree":
        return (
          <TreeView
            data={data}
            selectedNode={selectedNode}
            onNodeSelect={onNodeSelect}
            editable={config.editable}
            draggable={config.draggable}
            maxLevel={config.maxLevel}
          />
        );

      case "org":
        return <OrgView data={data} selectedNode={selectedNode} onNodeSelect={onNodeSelect} />;

      case "bom":
        return (
          <BomView data={data} selectedNode={selectedNode} onNodeSelect={onNodeSelect} editable={config.editable} />
        );

      case "dropdown":
      case "cascading":
        return (
          <CascadingView
            data={data}
            selectedNode={selectedNode}
            onNodeSelect={onNodeSelect}
            maxLevel={config.maxLevel}
          />
        );

      default:
        return <TreeView data={data} selectedNode={selectedNode} onNodeSelect={onNodeSelect} />;
    }
  };

  const showLabel = label && style?.labelDisplay !== false;
  const componentWidth = size?.width || style?.width;
  const componentHeight = size?.height || style?.height;

  // 라벨 높이 계산 (기본 20px, 사용자 설정에 따라 조정)
  const labelFontSize = style?.labelFontSize ? parseInt(String(style.labelFontSize)) : 14;
  const labelMarginBottom = style?.labelMarginBottom ? parseInt(String(style.labelMarginBottom)) : 4;
  const estimatedLabelHeight = labelFontSize + labelMarginBottom + 2;

  return (
    <div
      ref={ref}
      id={id}
      className="relative"
      style={{
        width: componentWidth,
        height: componentHeight,
      }}
    >
      {/* 🔧 라벨을 absolute로 컴포넌트 위에 배치 */}
      {showLabel && (
        <Label
          htmlFor={id}
          style={{
            position: "absolute",
            top: `-${estimatedLabelHeight}px`,
            left: 0,
            fontSize: style?.labelFontSize || "14px",
            color: getAdaptiveLabelColor(style?.labelColor),
            fontWeight: style?.labelFontWeight || "500",
          }}
          className="text-sm font-medium whitespace-nowrap"
        >
          {label}
          {required && <span className="ml-0.5 text-amber-500">*</span>}
        </Label>
      )}
      <div className="h-full w-full">{renderHierarchy()}</div>
    </div>
  );
});

V2Hierarchy.displayName = "V2Hierarchy";

export default V2Hierarchy;
