"use client";

/**
 * UnifiedHierarchy
 * 
 * 통합 계층 구조 컴포넌트
 * - 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 { UnifiedHierarchyProps, HierarchyNode } from "@/types/unified-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(
            "flex items-center gap-1 py-1 px-2 rounded cursor-pointer hover:bg-muted/50",
            isSelected && "bg-primary/10 text-primary"
          )}
          style={{ paddingLeft: `${level * 16 + 8}px` }}
          onClick={() => onSelect?.(node)}
        >
          {/* 드래그 핸들 */}
          {draggable && (
            <GripVertical className="h-4 w-4 text-muted-foreground 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="h-4 w-4 text-muted-foreground" />
          )}

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

          {/* 수량 (BOM용) */}
          {showQty && node.data?.qty && (
            <span className="text-xs text-muted-foreground bg-muted px-1.5 py-0.5 rounded">
              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("border rounded-lg p-2", className)}>
      {data.length === 0 ? (
        <div className="py-8 text-center text-muted-foreground 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(
            "flex flex-col items-center p-3 border rounded-lg cursor-pointer hover:border-primary transition-colors",
            isSelected && "border-primary bg-primary/5",
            isRoot && "bg-primary/10"
          )}
          onClick={() => onNodeSelect?.(node)}
        >
          <div className={cn(
            "w-10 h-10 rounded-full flex items-center justify-center mb-2",
            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="font-medium text-sm">{node.label}</div>
            {node.data?.title && (
              <div className="text-xs text-muted-foreground">{String(node.data.title)}</div>
            )}
          </div>
        </div>

        {/* 자식 노드 */}
        {hasChildren && (
          <>
            {/* 연결선 */}
            <div className="w-px h-4 bg-border" />
            <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="py-8 text-center text-muted-foreground 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("border rounded-lg p-2", className)}>
      {data.length === 0 ? (
        <div className="py-8 text-center text-muted-foreground 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";

/**
 * 메인 UnifiedHierarchy 컴포넌트
 */
export const UnifiedHierarchy = forwardRef<HTMLDivElement, UnifiedHierarchyProps>(
  (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;

    return (
      <div
        ref={ref}
        id={id}
        className="flex flex-col"
        style={{
          width: componentWidth,
          height: componentHeight,
        }}
      >
        {showLabel && (
          <Label
            htmlFor={id}
            style={{
              fontSize: style?.labelFontSize,
              color: style?.labelColor,
              fontWeight: style?.labelFontWeight,
              marginBottom: style?.labelMarginBottom,
            }}
            className="text-sm font-medium flex-shrink-0"
          >
            {label}
            {required && <span className="text-orange-500 ml-0.5">*</span>}
          </Label>
        )}
        <div className="flex-1 min-h-0">
          {renderHierarchy()}
        </div>
      </div>
    );
  }
);

UnifiedHierarchy.displayName = "UnifiedHierarchy";

export default UnifiedHierarchy;

