import React from "react";
import DOMPurify from "isomorphic-dompurify";
import {
  Check, Save, CheckCircle, CircleCheck, FileCheck, ShieldCheck,
  Trash2, Trash, XCircle, X, Eraser, CircleX,
  Pencil, PenLine, Pen, SquarePen, FilePen, PenTool,
  ArrowRight, ExternalLink, MoveRight, Navigation, CornerUpRight, Link,
  Maximize2, PanelTop, AppWindow, LayoutGrid, Layers, FolderOpen,
  SendHorizontal, ArrowRightLeft, Repeat, PackageCheck, Upload, Share2,
  Download, FileDown, FileSpreadsheet, Sheet, Table, FileOutput,
  FileUp, FileInput,
  Zap, Plus, PlusCircle, SquarePlus, FilePlus, BadgePlus,
  Settings, SlidersHorizontal, ToggleLeft, Workflow, GitBranch, Settings2,
  ScanLine, QrCode, Camera, Scan, ScanBarcode, Focus,
  Truck, Car, MapPin, Navigation2, Route, Bell,
  Send, Radio, Megaphone, Podcast, BellRing,
  Copy, ClipboardCopy, Files, CopyPlus, ClipboardList, Clipboard,
  SquareMousePointer,
  icons as allLucideIcons,
  type LucideIcon,
} from "lucide-react";

// ---------------------------------------------------------------------------
// 아이콘 이름 → 컴포넌트 매핑 (추천 아이콘은 명시적 import, 나머지는 동적 조회)
// ---------------------------------------------------------------------------
export const iconMap: Record<string, LucideIcon> = {
  Check, Save, CheckCircle, CircleCheck, FileCheck, ShieldCheck,
  Trash2, Trash, XCircle, X, Eraser, CircleX,
  Pencil, PenLine, Pen, SquarePen, FilePen, PenTool,
  ArrowRight, ExternalLink, MoveRight, Navigation, CornerUpRight, Link,
  Maximize2, PanelTop, AppWindow, LayoutGrid, Layers, FolderOpen,
  SendHorizontal, ArrowRightLeft, Repeat, PackageCheck, Upload, Share2,
  Download, FileDown, FileSpreadsheet, Sheet, Table, FileOutput,
  FileUp, FileInput,
  Zap, Plus, PlusCircle, SquarePlus, FilePlus, BadgePlus,
  Settings, SlidersHorizontal, ToggleLeft, Workflow, GitBranch, Settings2,
  ScanLine, QrCode, Camera, Scan, ScanBarcode, Focus,
  Truck, Car, MapPin, Navigation2, Route, Bell,
  Send, Radio, Megaphone, Podcast, BellRing,
  Copy, ClipboardCopy, Files, CopyPlus, ClipboardList, Clipboard,
  SquareMousePointer,
};

// ---------------------------------------------------------------------------
// 버튼 액션 → 추천 아이콘 이름 매핑
// ---------------------------------------------------------------------------
export const actionIconMap: Record<string, string[]> = {
  save: ["Check", "Save", "CheckCircle", "CircleCheck", "FileCheck", "ShieldCheck"],
  delete: ["Trash2", "Trash", "XCircle", "X", "Eraser", "CircleX"],
  edit: ["Pencil", "PenLine", "Pen", "SquarePen", "FilePen", "PenTool"],
  navigate: ["ArrowRight", "ExternalLink", "MoveRight", "Navigation", "CornerUpRight", "Link"],
  modal: ["Maximize2", "PanelTop", "AppWindow", "LayoutGrid", "Layers", "FolderOpen"],
  transferData: ["SendHorizontal", "ArrowRightLeft", "Repeat", "PackageCheck", "Upload", "Share2"],
  excel_download: ["Download", "FileDown", "FileSpreadsheet", "Sheet", "Table", "FileOutput"],
  excel_upload: ["Upload", "FileUp", "FileSpreadsheet", "Sheet", "FileInput", "FileOutput"],
  quickInsert: ["Zap", "Plus", "PlusCircle", "SquarePlus", "FilePlus", "BadgePlus"],
  control: ["Settings", "SlidersHorizontal", "ToggleLeft", "Workflow", "GitBranch", "Settings2"],
  barcode_scan: ["ScanLine", "QrCode", "Camera", "Scan", "ScanBarcode", "Focus"],
  operation_control: ["Truck", "Car", "MapPin", "Navigation2", "Route", "Bell"],
  event: ["Send", "Bell", "Radio", "Megaphone", "Podcast", "BellRing"],
  copy: ["Copy", "ClipboardCopy", "Files", "CopyPlus", "ClipboardList", "Clipboard"],
};

// 아이콘 추천이 불가능한 deprecated/숨김 액션
export const noIconActions = new Set([
  "openRelatedModal",
  "openModalWithData",
  "view_table_history",
  "code_merge",
  "empty_vehicle",
]);

export const NO_ICON_MESSAGE = "적절한 추천 아이콘이 없습니다. 텍스트 모드를 사용하거나 아래에서 아이콘을 직접 추가하세요.";

// 범용 폴백 아이콘 (추천 아이콘이 없는 액션용)
export const FALLBACK_ICON_NAME = "SquareMousePointer";

/** 액션 타입에 대한 디폴트 아이콘(첫 번째 추천)을 반환. 없으면 범용 폴백. */
export function getDefaultIconForAction(actionType?: string): { name: string; type: "lucide" } {
  if (actionType && actionIconMap[actionType]?.length) {
    return { name: actionIconMap[actionType][0], type: "lucide" };
  }
  return { name: FALLBACK_ICON_NAME, type: "lucide" };
}

// ---------------------------------------------------------------------------
// 아이콘 크기 (버튼 높이 대비 비율)
// ---------------------------------------------------------------------------
export const iconSizePresets: Record<string, number> = {
  "작게": 40,
  "보통": 55,
  "크게": 70,
  "매우 크게": 85,
};

/** 프리셋 문자열 → 비율(%) 반환. 레거시 값은 55(보통)로 폴백 */
export function getIconPercent(size: string | number): number {
  if (typeof size === "number") return size;
  return iconSizePresets[size] ?? 55;
}

/** 아이콘 크기를 CSS로 변환 (버튼 높이 대비 비율, 정사각형 유지) */
export function getIconSizeStyle(size: string | number): React.CSSProperties {
  const pct = getIconPercent(size);
  return { height: `${pct}%`, width: "auto", aspectRatio: "1 / 1" };
}

// ---------------------------------------------------------------------------
// 아이콘 조회 / 동적 등록
// iconMap에 없으면 lucide-react 전체 아이콘에서 동적 조회 후 캐싱
// ---------------------------------------------------------------------------
export function getLucideIcon(name: string): LucideIcon | undefined {
  if (iconMap[name]) return iconMap[name];

  const found = allLucideIcons[name as keyof typeof allLucideIcons];
  if (found) {
    iconMap[name] = found;
    return found;
  }

  return undefined;
}

export function addToIconMap(name: string, component: LucideIcon): void {
  iconMap[name] = component;
}

// ButtonConfigPanel 등에서 전체 아이콘 검색용으로 사용
export { allLucideIcons };

// ---------------------------------------------------------------------------
// SVG 정화
// ---------------------------------------------------------------------------
export function sanitizeSvg(svgString: string): string {
  return DOMPurify.sanitize(svgString, { USE_PROFILES: { svg: true } });
}

// ---------------------------------------------------------------------------
// 버튼 아이콘 렌더러 컴포넌트 (모든 뷰어/위젯에서 공용)
// ---------------------------------------------------------------------------
export function ButtonIconRenderer({
  componentConfig,
  fallbackLabel,
}: {
  componentConfig: any;
  fallbackLabel: string;
}) {
  const cfg = componentConfig || {};
  const displayMode = cfg.displayMode || "text";

  if (displayMode === "text" || !cfg.icon?.name) {
    return <>{cfg.text || fallbackLabel}</>;
  }

  return <>{getButtonDisplayContent(cfg)}</>;
}

// ---------------------------------------------------------------------------
// 버튼 표시 콘텐츠 계산 (모든 렌더러 공용)
// ---------------------------------------------------------------------------
export function getButtonDisplayContent(componentConfig: any): React.ReactNode {
  const displayMode = componentConfig?.displayMode || "text";
  const text = componentConfig?.text || componentConfig?.label || "버튼";
  const icon = componentConfig?.icon;

  if (displayMode === "text" || !icon?.name) {
    return text;
  }

  // 아이콘 노드 생성
  const sizeStyle = getIconSizeStyle(icon.size || "보통");
  const colorStyle: React.CSSProperties = icon.color ? { color: icon.color } : {};
  let iconNode: React.ReactNode = null;

  if (icon.type === "svg") {
    const svgIcon = componentConfig?.customSvgIcons?.find(
      (s: { name: string; svg: string }) => s.name === icon.name,
    );
    if (svgIcon) {
      const clean = sanitizeSvg(svgIcon.svg);
      iconNode = (
        <span
          className="inline-flex items-center justify-center [&>svg]:h-full [&>svg]:w-full"
          style={{ ...sizeStyle, ...colorStyle }}
          dangerouslySetInnerHTML={{ __html: clean }}
        />
      );
    }
  } else {
    const IconComponent = getLucideIcon(icon.name);
    if (IconComponent) {
      iconNode = (
        <span className="inline-flex items-center justify-center" style={sizeStyle}>
          <IconComponent className="h-full w-full" style={colorStyle} />
        </span>
      );
    }
  }

  if (!iconNode) {
    return text;
  }

  if (displayMode === "icon") {
    return iconNode;
  }

  // icon-text 모드
  const gap = componentConfig?.iconGap ?? 6;
  const textPos = componentConfig?.iconTextPosition || "right";
  const isVertical = textPos === "top" || textPos === "bottom";
  const textFirst = textPos === "left" || textPos === "top";

  return (
    <span
      className="inline-flex items-center justify-center"
      style={{
        gap: `${gap}px`,
        flexDirection: isVertical ? "column" : "row",
      }}
    >
      {textFirst ? <span>{text}</span> : iconNode}
      {textFirst ? iconNode : <span>{text}</span>}
    </span>
  );
}
