"use client";

import React, { useState, useMemo, useRef, useEffect, useCallback } from "react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
import { Search, X, ChevronDown } from "lucide-react";
import * as LucideIcons from "lucide-react";

type IconComponent = React.FC<{ className?: string }>;

// lucide-react에서 아이콘 컴포넌트만 필터링 (유틸 함수, 타입 등 제외)
const EXCLUDED_EXPORTS = new Set([
  "createLucideIcon",
  "defaultAttributes",
  "Icon",
  "icons",
  "default",
]);

// PascalCase인지 확인 (아이콘 컴포넌트는 모두 PascalCase)
const isPascalCase = (str: string): boolean => /^[A-Z][a-zA-Z0-9]*$/.test(str);

// 한글 키워드 매핑 (자주 쓰는 아이콘에 한글 검색어 추가)
const KOREAN_KEYWORDS: Record<string, string[]> = {
  Home: ["홈", "메인", "대시보드"],
  FileText: ["문서", "파일", "텍스트"],
  Users: ["사용자", "회원", "인사", "팀"],
  User: ["사용자", "회원", "개인"],
  Settings: ["설정", "관리", "시스템"],
  Shield: ["보안", "권한", "관리자"],
  Package: ["제품", "품목", "패키지", "상품"],
  BarChart3: ["통계", "차트", "분석", "리포트"],
  BarChart2: ["통계", "차트", "분석"],
  BarChart: ["통계", "차트"],
  Building2: ["회사", "조직", "건물", "부서"],
  Building: ["회사", "건물"],
  ShoppingCart: ["영업", "판매", "주문", "장바구니"],
  ShoppingBag: ["쇼핑", "가방", "구매"],
  Truck: ["물류", "배송", "운송", "출하"],
  Warehouse: ["창고", "재고", "입고"],
  Factory: ["생산", "공장", "제조"],
  Wrench: ["설비", "유지보수", "수리", "도구"],
  ClipboardCheck: ["품질", "검사", "체크리스트"],
  ClipboardList: ["작업지시", "지시서", "할일"],
  Clipboard: ["클립보드", "복사"],
  DollarSign: ["회계", "금액", "비용", "가격"],
  Receipt: ["영수증", "청구", "전표"],
  Calendar: ["일정", "캘린더", "날짜"],
  CalendarDays: ["일정", "캘린더", "날짜", "일"],
  Clock: ["시간", "이력", "히스토리"],
  FolderOpen: ["폴더", "분류", "카테고리"],
  Folder: ["폴더", "분류", "그룹"],
  FolderPlus: ["폴더추가", "분류추가"],
  Database: ["데이터", "DB", "저장소"],
  Globe: ["글로벌", "다국어", "웹", "세계"],
  Mail: ["메일", "이메일"],
  Bell: ["알림", "벨", "통지"],
  BellRing: ["알림", "벨", "울림"],
  Search: ["검색", "조회", "찾기"],
  ListOrdered: ["목록", "리스트", "순서"],
  List: ["목록", "리스트"],
  LayoutGrid: ["그리드", "레이아웃", "화면"],
  LayoutDashboard: ["대시보드", "레이아웃"],
  Tag: ["태그", "라벨", "분류"],
  Tags: ["태그", "라벨", "분류", "복수"],
  BookOpen: ["문서", "매뉴얼", "가이드"],
  Book: ["책", "문서"],
  Boxes: ["BOM", "자재", "부품", "구성"],
  Box: ["박스", "상자", "제품"],
  GitBranch: ["흐름", "분기", "프로세스"],
  Workflow: ["워크플로우", "플로우", "프로세스"],
  ArrowRightLeft: ["이동", "전환", "교환"],
  ArrowRight: ["오른쪽", "다음", "진행"],
  ArrowLeft: ["왼쪽", "이전", "뒤로"],
  ArrowUp: ["위", "상승", "업"],
  ArrowDown: ["아래", "하강", "다운"],
  Layers: ["레이어", "계층", "구조"],
  PieChart: ["파이차트", "통계", "비율"],
  TrendingUp: ["추세", "성장", "상승"],
  TrendingDown: ["추세", "하락", "하강"],
  AlertTriangle: ["경고", "주의"],
  AlertCircle: ["경고", "주의", "원"],
  CheckCircle: ["완료", "승인", "확인"],
  CheckCircle2: ["완료", "승인", "확인"],
  Check: ["확인", "체크"],
  Cog: ["톱니바퀴", "설정", "옵션"],
  Map: ["지도", "위치", "경로"],
  MapPin: ["지도핀", "위치", "장소"],
  Printer: ["프린터", "인쇄", "출력"],
  UserCog: ["사용자설정", "계정", "프로필"],
  UserPlus: ["사용자추가", "회원가입"],
  UserCheck: ["사용자확인", "인증"],
  Key: ["키", "권한", "인증", "보안"],
  Lock: ["잠금", "보안", "비밀번호"],
  LockOpen: ["잠금해제", "열기"],
  Unlock: ["잠금해제"],
  Hammer: ["작업", "공구", "수리"],
  Ruler: ["측정", "규격", "사양"],
  Scan: ["스캔", "바코드", "QR"],
  QrCode: ["QR코드", "큐알"],
  ScrollText: ["계약", "문서", "스크롤"],
  HandCoins: ["구매", "발주", "거래"],
  CircleDollarSign: ["매출", "수익", "원가"],
  FileSpreadsheet: ["엑셀", "스프레드시트", "표"],
  FilePlus2: ["신규", "추가", "등록"],
  FilePlus: ["파일추가", "신규"],
  FileCheck2: ["승인", "결재", "확인"],
  FileCheck: ["파일확인"],
  Zap: ["전기", "에너지", "빠른"],
  Gauge: ["게이지", "성능", "속도"],
  HardDrive: ["저장", "서버", "디스크"],
  Monitor: ["모니터", "화면", "디스플레이"],
  Smartphone: ["모바일", "스마트폰", "앱"],
  Lightbulb: ["아이디어", "제안", "개선"],
  Star: ["별", "즐겨찾기", "중요"],
  Heart: ["좋아요", "관심", "찜"],
  Bookmark: ["북마크", "저장", "즐겨찾기"],
  Flag: ["플래그", "깃발", "표시"],
  Award: ["수상", "인증", "포상"],
  Trophy: ["트로피", "우승", "성과"],
  Target: ["목표", "타겟", "대상"],
  Crosshair: ["크로스헤어", "조준", "정확"],
  Eye: ["보기", "조회", "미리보기"],
  EyeOff: ["숨기기", "비공개"],
  Image: ["이미지", "사진", "그림"],
  Camera: ["카메라", "사진", "촬영"],
  Video: ["비디오", "영상", "동영상"],
  Music: ["음악", "오디오", "사운드"],
  Mic: ["마이크", "음성", "녹음"],
  Phone: ["전화", "연락", "콜"],
  PhoneCall: ["통화", "전화"],
  MessageSquare: ["메시지", "채팅", "대화"],
  MessageCircle: ["메시지", "채팅"],
  Send: ["보내기", "전송", "발송"],
  Share2: ["공유", "전달"],
  Link: ["링크", "연결", "URL"],
  ExternalLink: ["외부링크", "새창"],
  Download: ["다운로드", "내려받기"],
  Upload: ["업로드", "올리기"],
  CloudUpload: ["클라우드업로드", "올리기"],
  CloudDownload: ["클라우드다운로드", "내려받기"],
  Cloud: ["클라우드", "구름"],
  Server: ["서버", "시스템"],
  Cpu: ["CPU", "프로세서", "처리"],
  Wifi: ["와이파이", "네트워크", "무선"],
  Activity: ["활동", "모니터링", "심박"],
  Thermometer: ["온도", "온도계", "측정"],
  Droplets: ["물", "수질", "액체"],
  Wind: ["바람", "공기", "환기"],
  Sun: ["태양", "밝기", "낮"],
  Moon: ["달", "야간", "다크모드"],
  Umbrella: ["우산", "보호", "보험"],
  Compass: ["나침반", "방향", "가이드"],
  Navigation: ["네비게이션", "안내"],
  RotateCcw: ["되돌리기", "새로고침", "초기화"],
  RefreshCw: ["새로고침", "갱신", "동기화"],
  Repeat: ["반복", "되풀이"],
  Shuffle: ["셔플", "무작위", "랜덤"],
  Filter: ["필터", "거르기", "조건"],
  SlidersHorizontal: ["슬라이더", "조정", "필터"],
  Maximize2: ["최대화", "전체화면"],
  Minimize2: ["최소화", "축소"],
  Move: ["이동", "옮기기"],
  Copy: ["복사", "복제"],
  Scissors: ["가위", "잘라내기"],
  Trash2: ["삭제", "쓰레기통", "휴지통"],
  Trash: ["삭제", "쓰레기"],
  Archive: ["보관", "아카이브", "저장"],
  ArchiveRestore: ["복원", "복구"],
  Plus: ["추가", "더하기", "플러스"],
  Minus: ["빼기", "마이너스", "제거"],
  PlusCircle: ["추가", "원형추가"],
  MinusCircle: ["제거", "원형제거"],
  XCircle: ["닫기", "취소", "제거"],
  Info: ["정보", "안내", "도움말"],
  HelpCircle: ["도움말", "질문", "안내"],
  CircleAlert: ["경고", "주의", "원형경고"],
  Ban: ["금지", "차단", "비허용"],
  ShieldCheck: ["보안확인", "인증완료"],
  ShieldAlert: ["보안경고", "위험"],
  LogIn: ["로그인", "접속"],
  LogOut: ["로그아웃", "종료"],
  Power: ["전원", "켜기/끄기"],
  ToggleLeft: ["토글", "스위치", "끄기"],
  ToggleRight: ["토글", "스위치", "켜기"],
  Percent: ["퍼센트", "비율", "할인"],
  Hash: ["해시", "번호", "코드"],
  AtSign: ["앳", "이메일", "골뱅이"],
  Code: ["코드", "개발", "프로그래밍"],
  Terminal: ["터미널", "명령어", "콘솔"],
  Table: ["테이블", "표", "데이터"],
  Table2: ["테이블", "표"],
  Columns: ["컬럼", "열", "항목"],
  Rows: ["행", "줄"],
  Grid3x3: ["그리드", "격자", "표"],
  PanelLeft: ["패널", "사이드바", "왼쪽"],
  PanelRight: ["패널", "사이드바", "오른쪽"],
  Split: ["분할", "나누기"],
  Combine: ["결합", "합치기"],
  Network: ["네트워크", "연결망"],
  Radio: ["라디오", "옵션"],
  CircleDot: ["원형점", "선택"],
  SquareCheck: ["체크박스", "선택"],
  Square: ["사각형", "상자"],
  Circle: ["원", "동그라미"],
  Triangle: ["삼각형", "세모"],
  Hexagon: ["육각형", "벌집"],
  Diamond: ["다이아몬드", "마름모"],
  Pen: ["펜", "작성", "편집"],
  Pencil: ["연필", "수정", "편집"],
  PenLine: ["펜라인", "서명"],
  Eraser: ["지우개", "삭제", "초기화"],
  Palette: ["팔레트", "색상", "디자인"],
  Paintbrush: ["브러시", "페인트", "디자인"],
  Figma: ["피그마", "디자인"],
  Type: ["타입", "글꼴", "폰트"],
  Bold: ["굵게", "볼드"],
  Italic: ["기울임", "이탤릭"],
  AlignLeft: ["왼쪽정렬"],
  AlignCenter: ["가운데정렬"],
  AlignRight: ["오른쪽정렬"],
  Footprints: ["발자국", "추적", "이력"],
  Fingerprint: ["지문", "인증", "보안"],
  ScanLine: ["스캔라인", "인식"],
  Barcode: ["바코드"],
  CreditCard: ["신용카드", "결제", "카드"],
  Wallet: ["지갑", "결제", "자금"],
  Banknote: ["지폐", "현금", "돈"],
  Coins: ["동전", "코인"],
  PiggyBank: ["저금통", "저축", "예산"],
  Landmark: ["랜드마크", "은행", "기관"],
  Store: ["매장", "상점", "가게"],
  GraduationCap: ["졸업", "교육", "학습"],
  School: ["학교", "교육", "훈련"],
  Library: ["도서관", "라이브러리"],
  BookMarked: ["북마크", "표시된책"],
  Notebook: ["노트북", "공책", "메모"],
  NotebookPen: ["노트작성", "메모"],
  FileArchive: ["압축파일", "아카이브"],
  FileAudio: ["오디오파일", "음악파일"],
  FileVideo: ["비디오파일", "영상파일"],
  FileImage: ["이미지파일", "사진파일"],
  FileCode: ["코드파일", "소스파일"],
  FileJson: ["JSON파일", "데이터파일"],
  FileCog: ["파일설정", "환경설정"],
  FileSearch: ["파일검색", "문서검색"],
  FileWarning: ["파일경고", "주의파일"],
  FileX: ["파일삭제", "파일제거"],
  Files: ["파일들", "다중파일"],
  FolderSearch: ["폴더검색"],
  FolderCog: ["폴더설정"],
  FolderInput: ["입력폴더", "수신"],
  FolderOutput: ["출력폴더", "발신"],
  FolderSync: ["폴더동기화"],
  FolderTree: ["폴더트리", "계층구조"],
  Inbox: ["받은편지함", "수신"],
  MailOpen: ["메일열기", "읽음"],
  MailPlus: ["메일추가", "새메일"],
  CalendarCheck: ["일정확인", "예약확인"],
  CalendarPlus: ["일정추가", "새일정"],
  CalendarX: ["일정취소", "일정삭제"],
  Timer: ["타이머", "시간측정"],
  Hourglass: ["모래시계", "대기", "로딩"],
  AlarmClock: ["알람", "시계"],
  Watch: ["시계", "손목시계"],
  Rocket: ["로켓", "출시", "배포"],
  Plane: ["비행기", "항공", "운송"],
  Ship: ["배", "선박", "해운"],
  Car: ["자동차", "차량"],
  Bus: ["버스", "대중교통"],
  Train: ["기차", "열차", "철도"],
  Bike: ["자전거", "이동"],
  Fuel: ["연료", "주유"],
  Construction: ["공사", "건설", "설치"],
  HardHat: ["안전모", "건설", "안전"],
  Shovel: ["삽", "건설", "시공"],
  Drill: ["드릴", "공구"],
  Nut: ["너트", "부품", "볼트"],
  Plug: ["플러그", "전원", "연결"],
  Cable: ["케이블", "선", "연결"],
  Battery: ["배터리", "충전"],
  BatteryCharging: ["충전중", "배터리"],
  Signal: ["신호", "강도"],
  Antenna: ["안테나", "수신"],
  Bluetooth: ["블루투스", "무선"],
  Usb: ["USB", "연결"],
  SquareStack: ["스택", "쌓기", "레이어"],
  Component: ["컴포넌트", "부품", "구성요소"],
  Puzzle: ["퍼즐", "조각", "모듈"],
  Blocks: ["블록", "구성요소"],
  GitCommit: ["커밋", "변경"],
  GitMerge: ["병합", "머지"],
  GitPullRequest: ["풀리퀘스트", "요청"],
  GitCompare: ["비교", "차이"],
  CirclePlay: ["재생", "플레이"],
  CirclePause: ["일시정지", "멈춤"],
  CircleStop: ["정지", "중지"],
  SkipForward: ["다음", "건너뛰기"],
  SkipBack: ["이전", "뒤로"],
  Volume2: ["볼륨", "소리"],
  VolumeX: ["음소거"],
  Headphones: ["헤드폰", "오디오"],
  Speaker: ["스피커", "소리"],
  Projector: ["프로젝터", "발표"],
  Presentation: ["프레젠테이션", "발표"],
  GanttChart: ["간트차트", "일정관리", "프로젝트"],
  KanbanSquare: ["칸반", "보드", "프로젝트"],
  ListTodo: ["할일목록", "체크리스트"],
  ListChecks: ["체크목록", "확인목록"],
  ListFilter: ["필터목록", "조건목록"],
  ListTree: ["트리목록", "계층목록"],
  StretchHorizontal: ["가로확장"],
  StretchVertical: ["세로확장"],
  Maximize: ["최대화"],
  Minimize: ["최소화"],
  Expand: ["확장", "펼치기"],
  Shrink: ["축소", "줄이기"],
  ZoomIn: ["확대"],
  ZoomOut: ["축소"],
  Focus: ["포커스", "집중"],
  Crosshairs: ["조준", "대상"],
  Locate: ["위치찾기", "현재위치"],
  LocateFixed: ["위치고정"],
  LocateOff: ["위치끄기"],
  Spline: ["스플라인", "곡선"],
  BrainCircuit: ["AI", "인공지능", "두뇌"],
  Brain: ["두뇌", "지능", "생각"],
  Bot: ["봇", "로봇", "자동화"],
  Sparkles: ["반짝", "AI", "마법"],
  Wand2: ["마법봉", "자동", "AI"],
  FlaskConical: ["실험", "연구", "시험"],
  TestTube: ["시험관", "검사", "테스트"],
  Microscope: ["현미경", "분석", "연구"],
  Stethoscope: ["청진기", "의료", "진단"],
  Syringe: ["주사기", "의료"],
  Pill: ["약", "의약품"],
  HeartPulse: ["심박", "건강", "의료"],
  Dna: ["DNA", "유전", "생명과학"],
  Atom: ["원자", "과학", "화학"],
  Beaker: ["비커", "실험", "화학"],
  Scale: ["저울", "무게", "측정"],
  Weight: ["무게", "중량"],
  Ratio: ["비율", "비교"],
  Calculator: ["계산기", "계산"],
  Binary: ["이진수", "코드"],
  Regex: ["정규식", "패턴"],
  Variable: ["변수", "값"],
  FunctionSquare: ["함수", "기능"],
  Braces: ["중괄호", "코드"],
  Brackets: ["대괄호", "배열"],
  Parentheses: ["소괄호", "그룹"],
  Tally5: ["집계", "카운트", "합계"],
  Sigma: ["시그마", "합계", "총합"],
  Infinity: ["무한", "반복"],
  Pi: ["파이", "수학"],
  Omega: ["오메가", "마지막"],
};

interface IconEntry {
  name: string;
  component: IconComponent;
  keywords: string[];
}

// 모든 Lucide 아이콘을 동적으로 가져오기
const ALL_ICONS: IconEntry[] = (() => {
  const entries: IconEntry[] = [];
  for (const [name, maybeComponent] of Object.entries(LucideIcons)) {
    if (EXCLUDED_EXPORTS.has(name)) continue;
    if (!isPascalCase(name)) continue;
    // lucide-react 아이콘은 forwardRef + memo로 감싸진 React 컴포넌트 (object)
    const comp = maybeComponent as any;
    const isReactComponent =
      typeof comp === "function" ||
      (typeof comp === "object" && comp !== null && comp.$$typeof);
    if (!isReactComponent) continue;

    const koreanKw = KOREAN_KEYWORDS[name] || [];
    entries.push({
      name,
      component: comp as IconComponent,
      keywords: [...koreanKw, name.toLowerCase()],
    });
  }
  return entries.sort((a, b) => a.name.localeCompare(b.name));
})();

export function getIconComponent(iconName: string | null | undefined): IconComponent | null {
  if (!iconName) return null;
  const entry = ALL_ICONS.find((e) => e.name === iconName);
  return entry?.component || null;
}

interface MenuIconPickerProps {
  value: string;
  onChange: (iconName: string) => void;
  label?: string;
}

export const MenuIconPicker: React.FC<MenuIconPickerProps> = ({
  value,
  onChange,
  label = "메뉴 아이콘",
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const [searchText, setSearchText] = useState("");
  const [visibleCount, setVisibleCount] = useState(120);
  const containerRef = useRef<HTMLDivElement>(null);
  const scrollRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setIsOpen(false);
        setSearchText("");
      }
    };
    if (isOpen) {
      document.addEventListener("mousedown", handleClickOutside);
    }
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, [isOpen]);

  // 드롭다운 열릴 때 표시 개수 초기화
  useEffect(() => {
    if (isOpen) setVisibleCount(120);
  }, [isOpen]);

  // 검색어 변경 시 표시 개수 초기화
  useEffect(() => {
    setVisibleCount(120);
  }, [searchText]);

  const filteredIcons = useMemo(() => {
    if (!searchText) return ALL_ICONS;
    const lower = searchText.toLowerCase();
    return ALL_ICONS.filter(
      (entry) =>
        entry.name.toLowerCase().includes(lower) ||
        entry.keywords.some((kw) => kw.includes(lower))
    );
  }, [searchText]);

  // 스크롤 끝에 도달하면 더 로드
  const handleScroll = useCallback(() => {
    const el = scrollRef.current;
    if (!el) return;
    if (el.scrollTop + el.clientHeight >= el.scrollHeight - 40) {
      setVisibleCount((prev) => Math.min(prev + 120, filteredIcons.length));
    }
  }, [filteredIcons.length]);

  const selectedIcon = ALL_ICONS.find((e) => e.name === value);
  const SelectedIconComponent = selectedIcon?.component;

  return (
    <div className="space-y-2">
      <Label>{label}</Label>
      <div className="relative" ref={containerRef}>
        <Button
          type="button"
          variant="outline"
          onClick={() => setIsOpen(!isOpen)}
          className="h-10 w-full justify-between text-sm"
        >
          <div className="flex items-center gap-2">
            {SelectedIconComponent ? (
              <>
                <SelectedIconComponent className="h-4 w-4" />
                <span>{selectedIcon?.name}</span>
              </>
            ) : (
              <span className="text-muted-foreground">아이콘을 선택하세요 (선택사항)</span>
            )}
          </div>
          {value ? (
            <X
              className="h-4 w-4 opacity-50 hover:opacity-100"
              onClick={(e) => {
                e.stopPropagation();
                onChange("");
                setIsOpen(false);
              }}
            />
          ) : (
            <ChevronDown className="h-4 w-4 opacity-50" />
          )}
        </Button>

        {isOpen && (
          <div className="bg-popover text-popover-foreground absolute top-full left-0 z-50 mt-1 w-full rounded-md border shadow-lg">
            <div className="border-b p-2">
              <div className="relative">
                <Search className="text-muted-foreground absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2" />
                <Input
                  placeholder="아이콘 검색 (한글/영문)..."
                  value={searchText}
                  onChange={(e) => setSearchText(e.target.value)}
                  className="h-8 pl-8 text-sm"
                  onClick={(e) => e.stopPropagation()}
                  autoFocus
                />
              </div>
            </div>

            <div
              ref={scrollRef}
              onScroll={handleScroll}
              className="max-h-72 overflow-y-auto p-2"
            >
              {!searchText && (
                <p className="text-muted-foreground mb-2 text-center text-xs">
                  총 {ALL_ICONS.length}개 아이콘
                </p>
              )}
              <div className="grid grid-cols-6 gap-1">
                {filteredIcons.slice(0, visibleCount).map((entry) => {
                  const IconComp = entry.component;
                  return (
                    <button
                      key={entry.name}
                      type="button"
                      title={entry.name}
                      onClick={() => {
                        onChange(entry.name);
                        setIsOpen(false);
                        setSearchText("");
                      }}
                      className={cn(
                        "flex flex-col items-center justify-center rounded-md p-2 transition-colors hover:bg-accent",
                        value === entry.name && "bg-primary/10 ring-primary ring-1"
                      )}
                    >
                      <IconComp className="h-5 w-5" />
                      <span className="mt-1 max-w-full truncate text-[9px] leading-tight">{entry.name}</span>
                    </button>
                  );
                })}
              </div>
              {filteredIcons.length === 0 && (
                <p className="text-muted-foreground py-4 text-center text-sm">
                  검색 결과가 없습니다.
                </p>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
};
