/**
 * 工作流表单生成器
 * 
 * 基于工作流模板的UI配置自动生成表单
 * 支持多种字段类型：文本、图片上传、选择框、滑块等
 * 遵循Tauri开发规范的组件设计原则
 */

import React, { useState, useCallback, useEffect, useRef } from 'react';
import { Upload, Image, FileText, Loader2, CheckCircle, XCircle, Sliders } from 'lucide-react';
import fileUploadService from '../../services/fileUploadService';
import type { FileUploadResult } from '../../types/comfyui';

// 工作流UI字段类型
export interface WorkflowUIField {
  name: string;
  type: 'text' | 'textarea' | 'number' | 'select' | 'checkbox' | 'image_upload' | 'file_upload' | 'slider' | 'color_picker';
  label: string;
  required: boolean;
  placeholder?: string;
  description?: string; // 字段描述
  default_value?: any;
  options?: string[];
  validation?: any;
  accept?: string; // for file uploads
  min?: number;    // for numbers/sliders
  max?: number;    // for numbers/sliders
  step?: number;   // for numbers/sliders
}

// 工作流UI配置
export interface WorkflowUIConfig {
  form_fields: WorkflowUIField[];
  layout?: any;
  theme?: string;
  custom_css?: string;
}

// 表单数据类型
export type WorkflowFormData = Record<string, any>;

interface WorkflowFormGeneratorProps {
  /** 工作流UI配置 */
  uiConfig: WorkflowUIConfig;
  /** 表单数据变化回调 */
  onFormDataChange?: (data: WorkflowFormData) => void;
  /** 表单提交回调 */
  onSubmit?: (data: WorkflowFormData) => void;
  /** 是否禁用表单 */
  disabled?: boolean;
  /** 自定义样式类名 */
  className?: string;
  /** 初始数据 */
  initialData?: WorkflowFormData;
}

/**
 * 工作流表单生成器组件
 */
export const WorkflowFormGenerator: React.FC<WorkflowFormGeneratorProps> = ({
  uiConfig,
  onFormDataChange,
  onSubmit,
  disabled = false,
  className = '',
  initialData = {}
}) => {
  const [formData, setFormData] = useState<WorkflowFormData>(initialData);
  const [uploadingFiles, setUploadingFiles] = useState<Set<string>>(new Set());
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [uploadStates, setUploadStates] = useState<Record<string, FileUploadResult>>({});
  const [dragOver, setDragOver] = useState<string | null>(null);

  // 获取字段类型的默认值
  const getDefaultValueForFieldType = (fieldType: string): any => {
    switch (fieldType) {
      case 'text':
      case 'textarea':
        return '';
      case 'number':
      case 'slider':
        return 0;
      case 'checkbox':
        return false;
      case 'select':
        return '';
      case 'image_upload':
      case 'file_upload':
        return null;
      case 'color':
        return '#000000';
      case 'date':
        return '';
      default:
        return '';
    }
  };

  // 初始化表单数据，确保所有字段都有默认值
  useEffect(() => {
    if (!uiConfig || !uiConfig.form_fields) return;

    setFormData(prev => {
      const initializedData: WorkflowFormData = {};

      // 为每个字段设置默认值
      uiConfig.form_fields.forEach(field => {
        // 优先使用当前值，然后是initialData中的值，然后是字段默认值，最后是类型默认值
        if (field.name in prev) {
          initializedData[field.name] = prev[field.name];
        } else if (field.name in initialData) {
          initializedData[field.name] = initialData[field.name];
        } else {
          initializedData[field.name] = field.default_value ?? getDefaultValueForFieldType(field.type);
        }
      });

      // 只有当数据真正不同时才返回新对象
      if (JSON.stringify(initializedData) !== JSON.stringify(prev)) {
        return initializedData;
      }
      return prev;
    });
  }, [uiConfig]);

  // 处理initialData变化（仅当有意义的数据时）
  useEffect(() => {
    if (!initialData || Object.keys(initialData).length === 0) return;

    // 使用函数式更新来避免依赖formData
    setFormData(prev => {
      // 检查是否有实际变化
      const hasChanges = Object.keys(initialData).some(key =>
        prev[key] !== initialData[key]
      );

      if (hasChanges) {
        return { ...prev, ...initialData };
      }
      return prev;
    });
  }, [JSON.stringify(initialData)]); // 使用JSON.stringify来深度比较

  // 单独的 useEffect 来通知父组件数据变化，避免渲染时调用
  useEffect(() => {
    if (onFormDataChange && Object.keys(formData).length > 0) {
      // 使用 setTimeout 确保在下一个事件循环中执行，避免渲染时状态更新
      const timeoutId = setTimeout(() => {
        onFormDataChange(formData);
      }, 0);

      return () => clearTimeout(timeoutId);
    }
  }, [formData, onFormDataChange]);

  // 更新表单数据
  const updateFormData = useCallback((fieldName: string, value: any) => {
    setFormData(prev => {
      const newData = { ...prev, [fieldName]: value };
      // 不在这里直接调用onFormDataChange，让useEffect处理
      return newData;
    });

    // 清除该字段的错误
    setErrors(prev => {
      if (prev[fieldName]) {
        const newErrors = { ...prev };
        delete newErrors[fieldName];
        return newErrors;
      }
      return prev;
    });
  }, []); // 移除onFormDataChange依赖

  // 验证表单
  const validateForm = useCallback(() => {
    const newErrors: Record<string, string> = {};
    
    uiConfig.form_fields.forEach(field => {
      if (field.required && (!formData[field.name] || formData[field.name] === '')) {
        newErrors[field.name] = `${field.label}是必填项`;
      }
      
      // 其他验证逻辑可以在这里添加
      if (field.validation) {
        // TODO: 实现JSON Schema验证
      }
    });
    
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  }, [uiConfig.form_fields, formData]);

  // 处理表单提交
  const handleSubmit = useCallback((e: React.FormEvent) => {
    e.preventDefault();
    if (validateForm()) {
      onSubmit?.(formData);
    }
  }, [formData, validateForm, onSubmit]);

  // 处理图片上传（点击选择文件）
  const handleImageUpload = useCallback(async (fieldName: string) => {
    setUploadingFiles(prev => new Set(prev).add(fieldName));

    try {
      // 设置上传状态
      setUploadStates(prev => ({
        ...prev,
        [fieldName]: { status: 'uploading', progress: 0 }
      }));

      // 选择并上传图片
      const result = await fileUploadService.selectAndUploadImage((progress) => {
        setUploadStates(prev => ({
          ...prev,
          [fieldName]: { status: 'uploading', progress }
        }));
      });

      // 更新上传状态
      setUploadStates(prev => ({
        ...prev,
        [fieldName]: result
      }));

      if (result.status === 'success' && result.url) {
        updateFormData(fieldName, result.url);
      } else {
        setErrors(prev => ({
          ...prev,
          [fieldName]: result.error || '上传失败'
        }));
      }
    } catch (error) {
      console.error('图片上传失败:', error);
      setUploadStates(prev => ({
        ...prev,
        [fieldName]: {
          status: 'error',
          error: error instanceof Error ? error.message : '上传失败',
          progress: 0
        }
      }));
      setErrors(prev => ({
        ...prev,
        [fieldName]: error instanceof Error ? error.message : '上传失败'
      }));
    } finally {
      setUploadingFiles(prev => {
        const newSet = new Set(prev);
        newSet.delete(fieldName);
        return newSet;
      });
    }
  }, [updateFormData]);

  // 处理文件拖拽上传
  const handleFileUpload = useCallback(async (fieldName: string, file: File) => {
    setUploadingFiles(prev => new Set(prev).add(fieldName));

    try {
      // 创建临时文件路径（这里需要实际的文件保存逻辑）
      // 暂时使用 URL.createObjectURL 作为占位符
      const fileUrl = URL.createObjectURL(file);
      updateFormData(fieldName, fileUrl);
    } catch (error) {
      console.error('文件上传失败:', error);
      setErrors(prev => ({ ...prev, [fieldName]: '文件上传失败' }));
    } finally {
      setUploadingFiles(prev => {
        const newSet = new Set(prev);
        newSet.delete(fieldName);
        return newSet;
      });
    }
  }, [updateFormData]);

  // 处理拖拽事件
  const handleDragEnter = useCallback((e: React.DragEvent, fieldName: string) => {
    e.preventDefault();
    e.stopPropagation();
    setDragOver(fieldName);
  }, []);

  const handleDragLeave = useCallback((e: React.DragEvent, fieldName: string) => {
    e.preventDefault();
    e.stopPropagation();
    // 只有当离开整个拖拽区域时才清除状态
    if (!e.currentTarget.contains(e.relatedTarget as Node)) {
      setDragOver(null);
    }
  }, []);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
  }, []);

  const handleDrop = useCallback((e: React.DragEvent, fieldName: string) => {
    e.preventDefault();
    e.stopPropagation();
    setDragOver(null);

    const files = Array.from(e.dataTransfer.files);
    if (files.length > 0) {
      const file = files[0];
      handleFileUpload(fieldName, file);
    }
  }, [handleFileUpload]);

  // 渲染字段
  const renderField = useCallback((field: WorkflowUIField) => {
    const rawValue = formData[field.name];
    const hasValue = rawValue !== undefined && rawValue !== null && rawValue !== '';
    const fieldValue = hasValue ? rawValue : (field.default_value ?? getDefaultValueForFieldType(field.type));
    const hasError = !!errors[field.name];
    const isUploading = uploadingFiles.has(field.name);

    const baseInputClasses = `
      w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500
      ${hasError ? 'border-red-500' : 'border-gray-300'}
      ${disabled ? 'bg-gray-100 cursor-not-allowed' : 'bg-white'}
    `;

    switch (field.type) {
      case 'text':
        return (
          <input
            type="text"
            value={fieldValue}
            onChange={(e) => updateFormData(field.name, e.target.value)}
            placeholder={field.placeholder}
            disabled={disabled}
            className={baseInputClasses}
          />
        );

      case 'textarea':
        return (
          <textarea
            value={hasValue ? fieldValue : ''}
            onChange={(e) => updateFormData(field.name, e.target.value)}
            placeholder={field.placeholder}
            disabled={disabled}
            rows={4}
            className={baseInputClasses}
          />
        );

      case 'number':
        return (
          <input
            type="number"
            value={hasValue ? fieldValue : ''}
            onChange={(e) => {
              const value = e.target.value;
              updateFormData(field.name, value === '' ? undefined : parseFloat(value));
            }}
            placeholder={field.placeholder}
            disabled={disabled}
            min={field.min || field.validation?.min}
            max={field.max || field.validation?.max}
            step={field.step || field.validation?.step}
            className={baseInputClasses}
          />
        );

      case 'select':
        return (
          <select
            value={fieldValue}
            onChange={(e) => updateFormData(field.name, e.target.value)}
            disabled={disabled}
            className={baseInputClasses}
          >
            <option value="">请选择...</option>
            {field.options?.map(option => (
              <option key={option} value={option}>{option}</option>
            ))}
          </select>
        );

      case 'checkbox':
        return (
          <div className="space-y-1">
            <label className="flex items-center space-x-2">
              <input
                type="checkbox"
                checked={!!fieldValue}
                onChange={(e) => updateFormData(field.name, e.target.checked)}
                disabled={disabled}
                className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
              />
              <span className="text-sm text-gray-700">{field.label}</span>
            </label>
            {field.description && (
              <p className="text-xs text-gray-500 ml-6">{field.description}</p>
            )}
          </div>
        );

      case 'image_upload':
      case 'file_upload':
        const uploadState = uploadStates[field.name];
        const hasImage = fieldValue && uploadState?.status === 'success';

        return (
          <div className="space-y-2">
            <div className={`
              border-2 border-dashed rounded-lg p-6 text-center transition-colors
              ${hasError ? 'border-red-300' :
                dragOver === field.name ? 'border-blue-400 bg-blue-50' : 'border-gray-300'}
              ${disabled ? 'bg-gray-50' : 'hover:border-gray-400 cursor-pointer'}
            `}
            onClick={() => {
              if (!disabled && !isUploading && field.type === 'image_upload') {
                handleImageUpload(field.name);
              }
            }}
            onDragEnter={(e) => handleDragEnter(e, field.name)}
            onDragLeave={(e) => handleDragLeave(e, field.name)}
            onDragOver={handleDragOver}
            onDrop={(e) => handleDrop(e, field.name)}
            >
              {isUploading ? (
                <div className="flex flex-col items-center space-y-2">
                  <Loader2 className="w-5 h-5 animate-spin" />
                  <span className="text-sm">上传中...</span>
                  {uploadState?.progress !== undefined && (
                    <div className="w-full bg-gray-200 rounded-full h-2">
                      <div
                        className="bg-blue-600 h-2 rounded-full transition-all duration-300"
                        style={{ width: `${uploadState.progress}%` }}
                      />
                    </div>
                  )}
                </div>
              ) : hasImage ? (
                <div className="flex flex-col items-center space-y-2">
                  <CheckCircle className="w-5 h-5 text-green-500" />
                  <span className="text-sm text-green-600">
                    {field.type === 'image_upload' ? '图片已上传' : '文件已上传'}
                  </span>
                  <button
                    type="button"
                    onClick={(e) => {
                      e.stopPropagation();
                      if (field.type === 'image_upload') {
                        handleImageUpload(field.name);
                      }
                    }}
                    disabled={disabled}
                    className="px-3 py-1 text-xs border border-gray-300 rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
                  >
                    重新上传
                  </button>
                </div>
              ) : (
                <div>
                  <Upload className={`w-8 h-8 mx-auto mb-2 ${
                    dragOver === field.name ? 'text-blue-500' : 'text-gray-400'
                  }`} />
                  <p className={`text-sm mb-1 ${
                    dragOver === field.name ? 'text-blue-600' : 'text-gray-600'
                  }`}>
                    {dragOver === field.name ? '释放文件以上传' : '点击或拖拽文件到此处上传'}
                  </p>
                  <p className="text-xs text-gray-500">
                    {field.type === 'image_upload' ? '支持 JPG, PNG, GIF 格式' : '支持所有文件格式'}
                  </p>
                </div>
              )}

              {/* 隐藏的文件输入，用于拖拽上传 */}
              <input
                type="file"
                accept={field.accept || (field.type === 'image_upload' ? 'image/*' : '*/*')}
                onChange={(e) => {
                  const file = e.target.files?.[0];
                  if (file) {
                    handleFileUpload(field.name, file);
                  }
                }}
                disabled={disabled || isUploading}
                className="hidden"
                id={`file-${field.name}`}
              />
            </div>

            {uploadState?.error && (
              <div className="text-xs text-red-600">
                {uploadState.error}
              </div>
            )}

            {hasImage && (
              <div className="text-xs text-gray-500">
                文件已成功上传到云端
              </div>
            )}
          </div>
        );

      case 'slider':
        return (
          <div className="space-y-2">
            <input
              type="range"
              value={fieldValue}
              onChange={(e) => updateFormData(field.name, parseFloat(e.target.value))}
              disabled={disabled}
              min={field.min || field.validation?.min}
              max={field.max || field.validation?.max}
              step={field.step || field.validation?.step}
              className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer"
            />
            <div className="flex justify-between text-xs text-gray-500">
              <span>{field.min || field.validation?.min}</span>
              <span className="font-medium">{fieldValue}</span>
              <span>{field.max || field.validation?.max}</span>
            </div>
          </div>
        );

      case 'color_picker':
        return (
          <input
            type="color"
            value={fieldValue}
            onChange={(e) => updateFormData(field.name, e.target.value)}
            disabled={disabled}
            className="w-full h-10 border border-gray-300 rounded cursor-pointer"
          />
        );

      default:
        return (
          <div className="text-red-500 text-sm">
            不支持的字段类型: {field.type}
          </div>
        );
    }
  }, [formData, errors, uploadingFiles, disabled, updateFormData, handleFileUpload]);

  return (
    <form onSubmit={handleSubmit} className={`space-y-6 ${className}`}>
      {uiConfig.form_fields.map(field => (
        <div key={field.name} className="space-y-2">
          {field.type !== 'checkbox' && (
            <div className="space-y-1">
              <label className="block text-sm font-medium text-gray-700">
                {field.label}
                {field.required && <span className="text-red-500 ml-1">*</span>}
              </label>
              {field.description && (
                <p className="text-xs text-gray-500">{field.description}</p>
              )}
            </div>
          )}

          {renderField(field)}

          {errors[field.name] && (
            <div className="flex items-center space-x-1 text-red-500 text-sm">
              <XCircle className="w-4 h-4" />
              <span>{errors[field.name]}</span>
            </div>
          )}
        </div>
      ))}
      
      {onSubmit && (
        <button
          type="submit"
          disabled={disabled || uploadingFiles.size > 0}
          className={`
            w-full py-2 px-4 rounded-lg font-medium transition-colors
            ${disabled || uploadingFiles.size > 0
              ? 'bg-gray-300 text-gray-500 cursor-not-allowed'
              : 'bg-blue-600 text-white hover:bg-blue-700'
            }
          `}
        >
          {uploadingFiles.size > 0 ? '上传中...' : '提交'}
        </button>
      )}
    </form>
  );
};
