'use client';

import { useState, useMemo, useCallback, useRef, useEffect } from 'react';
import { Search, X, ArrowRight, ArrowLeft, ChevronRight, ChevronLeft } from 'lucide-react';
import type { ComponentEntry } from './actions';

const TIER_CONFIG: Record<string, { label: string; color: string; bg: string; border: string; ring: string }> = {
  ui: { label: 'UI', color: 'text-blue-700', bg: 'bg-blue-50', border: 'border-blue-200', ring: 'ring-blue-200' },
  atoms: { label: 'Atoms', color: 'text-green-700', bg: 'bg-green-50', border: 'border-green-200', ring: 'ring-green-200' },
  molecules: { label: 'Molecules', color: 'text-purple-700', bg: 'bg-purple-50', border: 'border-purple-200', ring: 'ring-purple-200' },
  organisms: { label: 'Organisms', color: 'text-orange-700', bg: 'bg-orange-50', border: 'border-orange-200', ring: 'ring-orange-200' },
  common: { label: 'Common', color: 'text-teal-700', bg: 'bg-teal-50', border: 'border-teal-200', ring: 'ring-teal-200' },
  layout: { label: 'Layout', color: 'text-indigo-700', bg: 'bg-indigo-50', border: 'border-indigo-200', ring: 'ring-indigo-200' },
  dev: { label: 'Dev', color: 'text-yellow-700', bg: 'bg-yellow-50', border: 'border-yellow-200', ring: 'ring-yellow-200' },
  domain: { label: 'Domain', color: 'text-gray-700', bg: 'bg-gray-50', border: 'border-gray-200', ring: 'ring-gray-200' },
};

interface ComponentRelationshipViewProps {
  components: ComponentEntry[];
}

/** 카드형 플로우: 사용처(좌) → 선택 컴포넌트(중앙) → 구성요소(우) */
function FlowCard({
  comp,
  onSelect,
  size = 'normal',
}: {
  comp: ComponentEntry;
  onSelect: (filePath: string) => void;
  size?: 'normal' | 'large';
}) {
  const tc = TIER_CONFIG[comp.tier] || TIER_CONFIG.domain;
  const isLarge = size === 'large';

  return (
    <button
      onClick={() => onSelect(comp.filePath)}
      className={`
        group text-left rounded-lg border-2 transition-all w-full
        ${isLarge
          ? `${tc.border} ${tc.bg} p-4 shadow-md ring-2 ${tc.ring}`
          : 'border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-3 hover:shadow-md hover:border-blue-300 dark:hover:border-blue-500'
        }
      `}
    >
      <div className="flex items-center gap-2">
        <span className={`font-semibold ${isLarge ? 'text-base' : 'text-sm'} text-gray-900 dark:text-white truncate`}>
          {comp.name}
        </span>
        <span className={`text-[10px] px-1.5 py-0.5 rounded ${tc.bg} ${tc.color} ${tc.border} border shrink-0`}>
          {tc.label}
        </span>
      </div>
      <p className={`font-mono text-gray-400 mt-1 truncate ${isLarge ? 'text-xs' : 'text-[10px]'}`}>
        {comp.filePath.replace('src/components/', '')}
      </p>
      {isLarge && (
        <div className="flex gap-3 mt-2 text-xs text-gray-500">
          <span>{comp.imports.length}개 사용</span>
          <span>{comp.usedBy.length}곳에서 사용</span>
          <span>{comp.lineCount}L</span>
        </div>
      )}
    </button>
  );
}

/** 연결선 칼럼 (좌→중앙 또는 중앙→우 사이의 화살표 영역) */
function ConnectorColumn({ direction, count }: { direction: 'left' | 'right'; count: number }) {
  if (count === 0) return <div className="w-8 shrink-0" />;

  return (
    <div className="w-8 shrink-0 flex flex-col items-center justify-center gap-1">
      {direction === 'left' ? (
        <ArrowRight className="w-5 h-5 text-emerald-400" />
      ) : (
        <ArrowRight className="w-5 h-5 text-blue-400" />
      )}
    </div>
  );
}

/** 2차 카드 (클릭하면 그 컴포넌트의 imports/usedBy를 미니 리스트로 펼침) */
function ExpandableFlowCard({
  comp,
  componentMap,
  direction,
  onSelect,
}: {
  comp: ComponentEntry;
  componentMap: Map<string, ComponentEntry>;
  direction: 'usedBy' | 'imports';
  onSelect: (filePath: string) => void;
}) {
  const [expanded, setExpanded] = useState(false);
  const tc = TIER_CONFIG[comp.tier] || TIER_CONFIG.domain;
  const children = direction === 'usedBy' ? comp.usedBy : comp.imports;
  const resolvedChildren = children
    .map((fp) => componentMap.get(fp))
    .filter((c): c is ComponentEntry => c !== undefined);
  const hasChildren = resolvedChildren.length > 0;

  return (
    <div className="w-full">
      <div
        className="group flex items-center gap-2 rounded-lg border-2 border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-2.5 transition-all hover:shadow-md hover:border-blue-300 dark:hover:border-blue-500 cursor-pointer"
      >
        {/* 펼침 토글 */}
        {hasChildren ? (
          <button
            onClick={(e) => { e.stopPropagation(); setExpanded(!expanded); }}
            className="shrink-0 w-5 h-5 flex items-center justify-center text-gray-400 hover:text-gray-600"
          >
            {expanded ? <ChevronLeft className="w-3.5 h-3.5 rotate-[-90deg]" /> : <ChevronRight className="w-3.5 h-3.5 rotate-[-90deg]" />}
          </button>
        ) : (
          <div className="w-5 shrink-0" />
        )}

        {/* 메인 컨텐츠 (클릭 → 선택) */}
        <button onClick={() => onSelect(comp.filePath)} className="flex-1 text-left min-w-0">
          <div className="flex items-center gap-1.5">
            <span className="text-sm font-medium text-gray-900 dark:text-white truncate">
              {comp.name}
            </span>
            <span className={`text-[10px] px-1 py-0.5 rounded ${tc.bg} ${tc.color} ${tc.border} border shrink-0`}>
              {tc.label}
            </span>
          </div>
          <p className="text-[10px] font-mono text-gray-400 truncate mt-0.5">
            {comp.filePath.replace('src/components/', '')}
          </p>
        </button>

        {/* 카운트 뱃지 */}
        {hasChildren && (
          <span className="text-[10px] bg-gray-100 dark:bg-gray-700 text-gray-500 px-1.5 py-0.5 rounded-full shrink-0">
            {resolvedChildren.length}
          </span>
        )}
      </div>

      {/* 펼친 하위 목록 */}
      {expanded && hasChildren && (
        <div className="ml-4 mt-1 pl-3 border-l-2 border-gray-200 dark:border-gray-700 space-y-1">
          {resolvedChildren.slice(0, 10).map((child) => {
            const childTc = TIER_CONFIG[child.tier] || TIER_CONFIG.domain;
            return (
              <button
                key={child.filePath}
                onClick={() => onSelect(child.filePath)}
                className="w-full text-left flex items-center gap-1.5 px-2 py-1.5 rounded hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
              >
                <span className="text-xs text-gray-700 dark:text-gray-300 truncate">
                  {child.name}
                </span>
                <span className={`text-[9px] px-1 py-0.5 rounded ${childTc.bg} ${childTc.color} ${childTc.border} border shrink-0`}>
                  {childTc.label}
                </span>
              </button>
            );
          })}
          {resolvedChildren.length > 10 && (
            <p className="text-[10px] text-gray-400 px-2">+{resolvedChildren.length - 10}개 더...</p>
          )}
        </div>
      )}
    </div>
  );
}

export default function ComponentRelationshipView({ components }: ComponentRelationshipViewProps) {
  const [searchTerm, setSearchTerm] = useState('');
  const [selectedFilePath, setSelectedFilePath] = useState<string | null>(null);
  const [showDropdown, setShowDropdown] = useState(false);
  const [history, setHistory] = useState<string[]>([]);
  const dropdownRef = useRef<HTMLDivElement>(null);

  const componentMap = useMemo(() => {
    const map = new Map<string, ComponentEntry>();
    for (const comp of components) {
      map.set(comp.filePath, comp);
    }
    return map;
  }, [components]);

  const searchResults = useMemo(() => {
    if (!searchTerm) return [];
    const q = searchTerm.toLowerCase();
    return components
      .filter(
        (c) =>
          c.name.toLowerCase().includes(q) ||
          c.fileName.toLowerCase().includes(q) ||
          c.filePath.toLowerCase().includes(q)
      )
      .slice(0, 10);
  }, [components, searchTerm]);

  const selectedComponent = selectedFilePath ? componentMap.get(selectedFilePath) : null;

  const handleSelect = useCallback((filePath: string) => {
    setSelectedFilePath((prev) => {
      if (prev && prev !== filePath) {
        setHistory((h) => [...h.slice(-19), prev]);
      }
      return filePath;
    });
    setSearchTerm('');
    setShowDropdown(false);
  }, []);

  const handleBack = useCallback(() => {
    if (history.length === 0) return;
    const prev = history[history.length - 1];
    setHistory((h) => h.slice(0, -1));
    setSelectedFilePath(prev);
  }, [history]);

  useEffect(() => {
    function handleClickOutside(e: MouseEvent) {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {
        setShowDropdown(false);
      }
    }
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  // resolve usedBy/imports 컴포넌트 목록
  const usedByComponents = useMemo(() => {
    if (!selectedComponent) return [];
    return selectedComponent.usedBy
      .map((fp) => componentMap.get(fp))
      .filter((c): c is ComponentEntry => c !== undefined);
  }, [selectedComponent, componentMap]);

  const importComponents = useMemo(() => {
    if (!selectedComponent) return [];
    return selectedComponent.imports
      .map((fp) => componentMap.get(fp))
      .filter((c): c is ComponentEntry => c !== undefined);
  }, [selectedComponent, componentMap]);

  return (
    <div className="space-y-4">
      {/* 검색 입력 */}
      <div className="relative" ref={dropdownRef}>
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
        <input
          type="text"
          placeholder="컴포넌트 검색 후 선택..."
          value={searchTerm}
          onChange={(e) => {
            setSearchTerm(e.target.value);
            setShowDropdown(true);
          }}
          onFocus={() => { if (searchTerm) setShowDropdown(true); }}
          className="w-full pl-10 pr-10 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"
        />
        {searchTerm && (
          <button
            onClick={() => { setSearchTerm(''); setShowDropdown(false); }}
            className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
          >
            <X className="w-4 h-4" />
          </button>
        )}

        {showDropdown && searchResults.length > 0 && (
          <div className="absolute z-20 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg max-h-80 overflow-y-auto">
            {searchResults.map((comp) => {
              const tc = TIER_CONFIG[comp.tier] || TIER_CONFIG.domain;
              return (
                <button
                  key={comp.filePath}
                  onClick={() => handleSelect(comp.filePath)}
                  className="w-full text-left px-3 py-2 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors flex items-center gap-2"
                >
                  <span className="font-medium text-sm text-gray-900 dark:text-white">
                    {comp.name}
                  </span>
                  <span className={`text-[10px] px-1 py-0.5 rounded ${tc.bg} ${tc.color} ${tc.border} border`}>
                    {tc.label}
                  </span>
                  <span className="text-xs text-gray-400 ml-auto truncate max-w-[50%]">
                    {comp.filePath}
                  </span>
                </button>
              );
            })}
          </div>
        )}
      </div>

      {/* 선택 전 안내 */}
      {!selectedComponent && (
        <div className="text-center py-16 text-gray-400">
          <div className="flex items-center justify-center gap-3 mb-3">
            <div className="w-16 h-10 rounded border-2 border-dashed border-gray-300 flex items-center justify-center text-[10px] text-gray-300">
              사용처
            </div>
            <ArrowRight className="w-4 h-4 text-gray-300" />
            <div className="w-20 h-12 rounded border-2 border-dashed border-blue-300 flex items-center justify-center text-xs text-blue-300">
              선택
            </div>
            <ArrowRight className="w-4 h-4 text-gray-300" />
            <div className="w-16 h-10 rounded border-2 border-dashed border-gray-300 flex items-center justify-center text-[10px] text-gray-300">
              구성요소
            </div>
          </div>
          <p className="text-sm">컴포넌트를 검색하고 선택하면 관계도가 표시됩니다.</p>
          <p className="text-xs mt-1">카드를 클릭하면 해당 컴포넌트로 이동합니다.</p>
        </div>
      )}

      {/* 카드형 플로우 */}
      {selectedComponent && (
        <>
          {/* 뒤로가기 */}
          {history.length > 0 && (
            <button
              onClick={handleBack}
              className="flex items-center gap-1 text-xs text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 transition-colors"
            >
              <ArrowLeft className="w-3.5 h-3.5" />
              이전 컴포넌트
            </button>
          )}

          {/* 3칼럼 플로우 레이아웃 */}
          <div className="flex items-start gap-0">
            {/* 좌: 사용처 (이 컴포넌트를 사용하는 곳) */}
            <div className="flex-1 min-w-0">
              <div className="flex items-center gap-1.5 mb-3 px-1">
                <div className="w-2 h-2 rounded-full bg-emerald-400" />
                <span className="text-xs font-semibold text-gray-600 dark:text-gray-400 uppercase tracking-wider">
                  사용처
                </span>
                <span className="text-[10px] text-gray-400">
                  ({usedByComponents.length})
                </span>
              </div>
              {usedByComponents.length === 0 ? (
                <div className="text-center py-8">
                  <p className="text-xs text-gray-400">사용처 없음</p>
                  <p className="text-[10px] text-gray-300 mt-1">최상위 컴포넌트</p>
                </div>
              ) : (
                <div className="space-y-2 max-h-[600px] overflow-y-auto pr-1">
                  {usedByComponents.map((comp) => (
                    <ExpandableFlowCard
                      key={comp.filePath}
                      comp={comp}
                      componentMap={componentMap}
                      direction="usedBy"
                      onSelect={handleSelect}
                    />
                  ))}
                </div>
              )}
            </div>

            {/* 연결선 좌→중앙 */}
            <ConnectorColumn direction="left" count={usedByComponents.length} />

            {/* 중앙: 선택된 컴포넌트 */}
            <div className="w-[260px] shrink-0">
              <div className="flex items-center gap-1.5 mb-3 px-1 justify-center">
                <div className="w-2 h-2 rounded-full bg-blue-500" />
                <span className="text-xs font-semibold text-gray-600 dark:text-gray-400 uppercase tracking-wider">
                  선택됨
                </span>
              </div>
              <FlowCard comp={selectedComponent} onSelect={handleSelect} size="large" />
            </div>

            {/* 연결선 중앙→우 */}
            <ConnectorColumn direction="right" count={importComponents.length} />

            {/* 우: 구성요소 (이 컴포넌트가 사용하는 것) */}
            <div className="flex-1 min-w-0">
              <div className="flex items-center gap-1.5 mb-3 px-1">
                <div className="w-2 h-2 rounded-full bg-blue-400" />
                <span className="text-xs font-semibold text-gray-600 dark:text-gray-400 uppercase tracking-wider">
                  구성요소
                </span>
                <span className="text-[10px] text-gray-400">
                  ({importComponents.length})
                </span>
              </div>
              {importComponents.length === 0 ? (
                <div className="text-center py-8">
                  <p className="text-xs text-gray-400">구성요소 없음</p>
                  <p className="text-[10px] text-gray-300 mt-1">기본 컴포넌트 (leaf)</p>
                </div>
              ) : (
                <div className="space-y-2 max-h-[600px] overflow-y-auto pl-1">
                  {importComponents.map((comp) => (
                    <ExpandableFlowCard
                      key={comp.filePath}
                      comp={comp}
                      componentMap={componentMap}
                      direction="imports"
                      onSelect={handleSelect}
                    />
                  ))}
                </div>
              )}
            </div>
          </div>

          {/* 범례 */}
          <div className="flex items-center justify-center gap-6 pt-4 border-t border-gray-200 dark:border-gray-700">
            <div className="flex items-center gap-1.5 text-[10px] text-gray-400">
              <div className="w-2 h-2 rounded-full bg-emerald-400" />
              사용처: 이 컴포넌트를 import하는 곳
            </div>
            <div className="flex items-center gap-1.5 text-[10px] text-gray-400">
              <div className="w-2 h-2 rounded-full bg-blue-400" />
              구성요소: 이 컴포넌트가 import하는 것
            </div>
            <div className="flex items-center gap-1.5 text-[10px] text-gray-400">
              카드 클릭 = 해당 컴포넌트로 이동
            </div>
          </div>
        </>
      )}
    </div>
  );
}
