import { useState, useMemo } from 'react';
import { 
  Plus, 
  Trash2, 
  Settings2, 
  Layout, 
  Type, 
  Square, 
  CheckSquare, 
  Smartphone, 
  Monitor,
  Eye,
  Code,
  Save,
  Download
} from 'lucide-react';
import { v4 as uuidv4 } from 'uuid';
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';

// 样式合并工具函数
function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

// 组件类型定义
type ComponentType = 'text' | 'button' | 'input' | 'card' | 'checkbox';

interface VisualComponent {
  id: string;
  type: ComponentType;
  props: Record<string, any>;
}

// 可选组件库
const COMPONENT_LIBRARY = [
  { type: 'text' as const, label: '文本', icon: Type, defaultProps: { text: '点击编辑文本', fontSize: '16px', color: '#000000' } },
  { type: 'button' as const, label: '按钮', icon: Square, defaultProps: { label: '点击按钮', variant: 'primary', width: 'auto' } },
  { type: 'input' as const, label: '输入框', icon: Type, defaultProps: { placeholder: '请输入内容...', label: '表单字段' } },
  { type: 'card' as const, label: '卡片容器', icon: Layout, defaultProps: { title: '卡片标题', content: '这里是卡片内容区域' } },
  { type: 'checkbox' as const, label: '复选框', icon: CheckSquare, defaultProps: { label: '选项名称', checked: false } },
];

/**
 * 极简可视化低代码平台 - 核心入口组件
 * 支持组件库拖拽、画布渲染、属性实时编辑及多端预览
 */
export default function App() {
  // --- 状态管理 ---
  const [components, setComponents] = useState<VisualComponent[]>([]); // 画布上的组件列表
  const [selectedId, setSelectedId] = useState<string | null>(null);   // 当前选中的组件 ID
  const [viewMode, setViewMode] = useState<'desktop' | 'mobile'>('desktop'); // 预览模式：桌面/移动端
  const [isPreview, setIsPreview] = useState(false);                   // 是否处于预览模式

  // 获取当前选中的组件对象
  const selectedComponent = useMemo(() => 
    components.find(c => c.id === selectedId), 
    [components, selectedId]
  );

  // 添加新组件到画布
  const addComponent = (type: ComponentType, defaultProps: any) => {
    const newComp: VisualComponent = {
      id: uuidv4(),
      type,
      props: { ...defaultProps }
    };
    setComponents([...components, newComp]);
    setSelectedId(newComp.id);
  };

  // 从画布中移除组件
  const removeComponent = (id: string) => {
    setComponents(components.filter(c => c.id !== id));
    if (selectedId === id) setSelectedId(null);
  };

  // 更新选中组件的属性
  const updateProps = (id: string, newProps: any) => {
    setComponents(components.map(c => 
      c.id === id ? { ...c, props: { ...c.props, ...newProps } } : c
    ));
  };

  // 渲染单个可视化组件
  const renderComponent = (comp: VisualComponent, index: number) => {
    const isSelected = selectedId === comp.id;
    
    const wrapperClass = cn(
      "relative group cursor-pointer border-2 border-transparent transition-all",
      !isPreview && isSelected && "border-blue-500 rounded-lg",
      !isPreview && !isSelected && "hover:border-dashed hover:border-gray-300 rounded-lg"
    );

    const commonProps = {
      onClick: (e: React.MouseEvent) => {
        if (isPreview) return;
        e.stopPropagation();
        setSelectedId(comp.id);
      }
    };

    let element;
    switch (comp.type) {
      case 'text':
        element = (
          <div style={{ fontSize: comp.props.fontSize, color: comp.props.color }}>
            {comp.props.text}
          </div>
        );
        break;
      case 'button':
        element = (
          <button className={cn(
            "px-4 py-2 rounded font-medium transition-colors",
            comp.props.variant === 'primary' ? "bg-blue-600 text-white" : "bg-gray-200 text-gray-800",
            comp.props.width === 'full' ? "w-full" : "w-auto"
          )}>
            {comp.props.label}
          </button>
        );
        break;
      case 'input':
        element = (
          <div className="flex flex-col gap-1">
            <label className="text-sm font-medium text-gray-700">{comp.props.label}</label>
            <input 
              type="text" 
              placeholder={comp.props.placeholder}
              className="px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 outline-none"
              disabled={!isPreview}
            />
          </div>
        );
        break;
      case 'card':
        element = (
          <div className="bg-white p-4 rounded-xl shadow-sm border border-gray-100">
            <h3 className="text-lg font-bold mb-2">{comp.props.title}</h3>
            <p className="text-gray-600">{comp.props.content}</p>
          </div>
        );
        break;
      case 'checkbox':
        element = (
          <label className="flex items-center gap-2 cursor-pointer">
            <input type="checkbox" checked={comp.props.checked} readOnly={!isPreview} className="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500" />
            <span className="text-gray-700">{comp.props.label}</span>
          </label>
        );
        break;
    }

    return (
      <div key={comp.id} className={wrapperClass} {...commonProps}>
        {element}
        {!isPreview && isSelected && (
          <button 
            onClick={(e) => { e.stopPropagation(); removeComponent(comp.id); }}
            className="absolute -top-3 -right-3 bg-red-500 text-white p-1 rounded-full shadow-lg opacity-0 group-hover:opacity-100 transition-opacity"
          >
            <Trash2 size={14} />
          </button>
        )}
      </div>
    );
  };

  return (
    <div className="flex h-screen bg-gray-50 text-gray-900 font-sans overflow-hidden">
      {/* 顶部工具栏 */}
      <div className="absolute top-0 left-0 right-0 h-14 bg-white border-b border-gray-200 flex items-center justify-between px-6 z-50 shadow-sm">
        <div className="flex items-center gap-2">
          <div className="bg-blue-600 p-1.5 rounded-lg">
            <Code className="text-white" size={20} />
          </div>
          <span className="font-bold text-lg tracking-tight">极简低代码平台</span>
        </div>

        <div className="flex items-center gap-4 bg-gray-100 p-1 rounded-lg">
          <button 
            onClick={() => setViewMode('desktop')}
            className={cn("p-1.5 rounded-md transition-all", viewMode === 'desktop' ? "bg-white shadow-sm text-blue-600" : "text-gray-500")}
          >
            <Monitor size={18} />
          </button>
          <button 
            onClick={() => setViewMode('mobile')}
            className={cn("p-1.5 rounded-md transition-all", viewMode === 'mobile' ? "bg-white shadow-sm text-blue-600" : "text-gray-500")}
          >
            <Smartphone size={18} />
          </button>
        </div>

        <div className="flex items-center gap-3">
          <button 
            onClick={() => setIsPreview(!isPreview)}
            className={cn(
              "flex items-center gap-2 px-4 py-1.5 rounded-lg font-medium transition-all",
              isPreview ? "bg-orange-100 text-orange-600" : "bg-blue-50 text-blue-600 hover:bg-blue-100"
            )}
          >
            {isPreview ? <Save size={18} /> : <Eye size={18} />}
            {isPreview ? "退出预览" : "预览"}
          </button>
          <button className="bg-blue-600 text-white px-4 py-1.5 rounded-lg font-medium hover:bg-blue-700 transition-all flex items-center gap-2">
            <Download size={18} />
            发布
          </button>
        </div>
      </div>

      {/* 左侧组件库 */}
      {!isPreview && (
        <aside className="w-72 bg-white border-r border-gray-200 mt-14 flex flex-col z-40">
          <div className="p-4 border-b border-gray-100">
            <h2 className="text-sm font-semibold text-gray-400 uppercase tracking-wider">组件库</h2>
          </div>
          <div className="flex-1 overflow-y-auto p-4 space-y-3">
            {COMPONENT_LIBRARY.map((item) => (
              <button
                key={item.type}
                onClick={() => addComponent(item.type, item.defaultProps)}
                className="w-full flex items-center gap-3 p-3 bg-gray-50 hover:bg-blue-50 border border-gray-100 hover:border-blue-200 rounded-xl transition-all group text-left"
              >
                <div className="p-2 bg-white rounded-lg shadow-sm group-hover:text-blue-600 transition-colors">
                  <item.icon size={18} />
                </div>
                <span className="font-medium text-gray-700 group-hover:text-blue-600">{item.label}</span>
                <Plus size={16} className="ml-auto text-gray-300 group-hover:text-blue-400" />
              </button>
            ))}
          </div>
        </aside>
      )}

      {/* 中间画布 */}
      <main className={cn(
        "flex-1 mt-14 overflow-auto p-8 flex justify-center transition-all duration-300 bg-gray-50",
        isPreview && "p-0 bg-white"
      )}>
        <div 
          className={cn(
            "bg-white shadow-2xl transition-all duration-300 border border-gray-200 min-h-full",
            viewMode === 'mobile' ? "w-[375px] rounded-[40px] border-[12px] border-gray-800 p-8 my-4" : "w-full max-w-4xl rounded-xl p-10",
            isPreview && viewMode === 'desktop' && "max-w-none w-full border-none shadow-none rounded-none",
            isPreview && viewMode === 'mobile' && "my-8"
          )}
          onClick={() => setSelectedId(null)}
        >
          {components.length === 0 ? (
            <div className="h-full flex flex-col items-center justify-center text-gray-400 gap-4 mt-20">
              <div className="bg-gray-100 p-6 rounded-full">
                <Layout size={48} />
              </div>
              <p className="text-lg">从左侧拖拽或点击组件开始设计</p>
            </div>
          ) : (
            <div className="space-y-6">
              {components.map((comp, index) => renderComponent(comp, index))}
            </div>
          )}
        </div>
      </main>

      {/* 右侧属性面板 */}
      {!isPreview && (
        <aside className="w-80 bg-white border-l border-gray-200 mt-14 flex flex-col z-40">
          <div className="p-4 border-b border-gray-100 flex items-center gap-2">
            <Settings2 size={18} className="text-blue-600" />
            <h2 className="text-sm font-semibold text-gray-700">属性配置</h2>
          </div>
          <div className="flex-1 overflow-y-auto p-5">
            {selectedComponent ? (
              <div className="space-y-6">
                <div className="bg-blue-50 p-3 rounded-lg border border-blue-100">
                  <span className="text-xs font-bold text-blue-600 uppercase">当前组件: {selectedComponent.type}</span>
                </div>
                
                {/* 根据组件类型显示不同的编辑项 */}
                <div className="space-y-4">
                  {Object.entries(selectedComponent.props).map(([key, value]) => (
                    <div key={key} className="space-y-1.5">
                      <label className="text-xs font-medium text-gray-500 uppercase">{key === 'text' ? '文本内容' : key === 'label' ? '标签' : key === 'fontSize' ? '字号' : key === 'color' ? '颜色' : key === 'placeholder' ? '提示词' : key === 'title' ? '标题' : key === 'content' ? '正文' : key === 'variant' ? '样式' : key === 'width' ? '宽度' : key}</label>
                      {typeof value === 'string' && (key !== 'variant' && key !== 'width') ? (
                        <input 
                          type={key === 'color' ? 'color' : 'text'}
                          value={value}
                          onChange={(e) => updateProps(selectedComponent.id, { [key]: e.target.value })}
                          className="w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 outline-none text-sm"
                        />
                      ) : key === 'variant' ? (
                        <select 
                          value={value}
                          onChange={(e) => updateProps(selectedComponent.id, { [key]: e.target.value })}
                          className="w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg outline-none text-sm"
                        >
                          <option value="primary">主按钮</option>
                          <option value="secondary">次按钮</option>
                        </select>
                      ) : key === 'width' ? (
                        <select 
                          value={value}
                          onChange={(e) => updateProps(selectedComponent.id, { [key]: e.target.value })}
                          className="w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg outline-none text-sm"
                        >
                          <option value="auto">自适应</option>
                          <option value="full">撑满</option>
                        </select>
                      ) : null}
                    </div>
                  ))}
                </div>
              </div>
            ) : (
              <div className="h-full flex flex-col items-center justify-center text-gray-400 text-sm gap-2">
                <Smartphone size={32} strokeWidth={1.5} />
                <p>选中画布上的组件进行编辑</p>
              </div>
            )}
          </div>
        </aside>
      )}
    </div>
  );
}
