/**
 * WorkflowEditor - OpenFang Workflow Editor Component
 *
 * Allows creating and editing multi-step workflows that chain
 * multiple Hands together for complex task automation.
 *
 * Design based on OpenFang Dashboard v0.4.0
 */

import { useState, useEffect, useCallback } from 'react';
import { useHandStore, type Hand } from '../store/handStore';
import { useWorkflowStore, type Workflow } from '../store/workflowStore';
import {
  X,
  Plus,
  Trash2,
  GripVertical,
  ChevronDown,
  ChevronUp,
  ChevronLeft,
  ChevronRight,
  Save,
  Loader2,
  AlertCircle,
  GitBranch,
} from 'lucide-react';
import { safeJsonParse } from '../lib/json-utils';

// === Types ===

interface WorkflowStep {
  id: string;
  handName: string;
  name?: string;
  params?: Record<string, unknown>;
  condition?: string;
}

interface WorkflowEditorProps {
  workflow?: Workflow; // If provided, edit mode; otherwise create mode
  isOpen: boolean;
  onClose: () => void;
  onSave: (data: {
    name: string;
    description?: string;
    steps: Array<{
      handName: string;
      name?: string;
      params?: Record<string, unknown>;
      condition?: string;
    }>;
  }) => Promise<void>;
  isSaving: boolean;
}

// === Step Editor Component ===

interface StepEditorProps {
  step: WorkflowStep;
  hands: Hand[];
  index: number;
  onUpdate: (step: WorkflowStep) => void;
  onRemove: () => void;
  onMoveUp?: () => void;
  onMoveDown?: () => void;
}

function StepEditor({ step, hands, index, onUpdate, onRemove, onMoveUp, onMoveDown }: StepEditorProps) {
  const [isExpanded, setIsExpanded] = useState(true);
  const selectedHand = hands.find(h => h.name === step.handName);

  return (
    <div className="bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700">
      {/* Header */}
      <div className="flex items-center gap-2 p-3 border-b border-gray-200 dark:border-gray-700">
        <GripVertical className="w-4 h-4 text-gray-400 cursor-grab" />
        <span className="flex-shrink-0 w-6 h-6 bg-blue-100 dark:bg-blue-900/30 rounded-full flex items-center justify-center text-xs font-medium text-blue-600 dark:text-blue-400">
          {index + 1}
        </span>
        <div className="flex-1 min-w-0">
          <select
            value={step.handName}
            onChange={(e) => onUpdate({ ...step, handName: e.target.value })}
            className="w-full px-2 py-1.5 text-sm border border-gray-200 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
          >
            <option value="">选择 Hand...</option>
            {hands.map(hand => (
              <option key={hand.id} value={hand.id}>
                {hand.name} - {hand.description}
              </option>
            ))}
          </select>
        </div>
        <button
          onClick={() => setIsExpanded(!isExpanded)}
          className="p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
        >
          {isExpanded ? <ChevronUp className="w-4 h-4" /> : <ChevronDown className="w-4 h-4" />}
        </button>
        {onMoveUp && (
          <button
            onClick={onMoveUp}
            className="p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 rounded"
            title="上移"
          >
            <ChevronLeft className="w-4 h-4" />
          </button>
        )}
        {onMoveDown && (
          <button
            onClick={onMoveDown}
            className="p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 rounded"
            title="下移"
          >
            <ChevronRight className="w-4 h-4" />
          </button>
        )}
        <button
          onClick={onRemove}
          className="p-1 text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded"
        >
          <Trash2 className="w-4 h-4" />
        </button>
      </div>

      {/* Expanded Content */}
      {isExpanded && (
        <div className="p-3 space-y-3">
          {/* Step Name */}
          <div>
            <label className="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">
              步骤名称 (可选)
            </label>
            <input
              type="text"
              value={step.name || ''}
              onChange={(e) => onUpdate({ ...step, name: e.target.value || undefined })}
              placeholder={`${step.handName || '步骤'} ${index + 1}`}
              className="w-full px-2 py-1.5 text-sm border border-gray-200 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>

          {/* Condition */}
          <div>
            <label className="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">
              执行条件 (可选)
            </label>
            <input
              type="text"
              value={step.condition || ''}
              onChange={(e) => onUpdate({ ...step, condition: e.target.value || undefined })}
              placeholder="例如: previous_result.success == true"
              className="w-full px-2 py-1.5 text-sm border border-gray-200 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
            <p className="mt-1 text-xs text-gray-400 dark:text-gray-500">
              使用表达式决定是否执行此步骤
            </p>
          </div>

          {/* Parameters */}
          <div>
            <label className="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">
              参数 (JSON 格式)
            </label>
            <textarea
              value={step.params ? JSON.stringify(step.params, null, 2) : ''}
              onChange={(e) => {
                const text = e.target.value.trim();
                if (text) {
                  const result = safeJsonParse<Record<string, unknown>>(text);
                  if (result.success) {
                    onUpdate({ ...step, params: result.data });
                  }
                  // If parse fails, keep current params
                } else {
                  onUpdate({ ...step, params: undefined });
                }
              }}
              placeholder='{"key": "value"}'
              rows={3}
              className="w-full px-2 py-1.5 text-sm font-mono border border-gray-200 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>

          {/* Hand Info */}
          {selectedHand && (
            <div className="p-2 bg-blue-50 dark:bg-blue-900/20 rounded-md text-xs text-blue-700 dark:text-blue-400">
              <div className="font-medium mb-1">{selectedHand.description}</div>
              {selectedHand.toolCount && (
                <div>工具数量: {selectedHand.toolCount}</div>
              )}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// === Main WorkflowEditor Component ===

export function WorkflowEditor({ workflow, isOpen, onClose, onSave, isSaving }: WorkflowEditorProps) {
  const hands = useHandStore((s) => s.hands);
  const loadHands = useHandStore((s) => s.loadHands);
  const getWorkflowDetail = useWorkflowStore((s) => s.getWorkflowDetail);
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [steps, setSteps] = useState<WorkflowStep[]>([]);
  const [error, setError] = useState<string | null>(null);

  const isEditMode = !!workflow;

  // Load hands on mount
  useEffect(() => {
    loadHands();
  }, [loadHands]);

  // Initialize form when workflow changes (edit mode)
  useEffect(() => {
    if (workflow) {
      setName(workflow.name);
      setDescription(workflow.description || '');
      
      // Load full workflow details including steps
      getWorkflowDetail(workflow.id)
        .then((detail: { steps: Array<{ handName: string; name?: string; params?: Record<string, unknown>; condition?: string }> } | undefined) => {
          if (detail && Array.isArray(detail.steps)) {
            const editorSteps: WorkflowStep[] = detail.steps.map((step: { handName: string; name?: string; params?: Record<string, unknown>; condition?: string }, index: number) => ({
              id: `step-${workflow.id}-${index}`,
              handName: step.handName || '',
              name: step.name,
              params: step.params,
              condition: step.condition,
            }));
            setSteps(editorSteps);
          } else {
            setSteps([]);
          }
        })
        .catch(() => setSteps([]));
    } else {
      setName('');
      setDescription('');
      setSteps([]);
    }
    setError(null);
  }, [workflow, getWorkflowDetail]);

  // Add new step
  const handleAddStep = useCallback(() => {
    const newStep: WorkflowStep = {
      id: `step-${Date.now()}`,
      handName: '',
    };
    setSteps(prev => [...prev, newStep]);
  }, []);

  // Update step
  const handleUpdateStep = useCallback((index: number, updatedStep: WorkflowStep) => {
    setSteps(prev => prev.map((s, i) => i === index ? updatedStep : s));
  }, []);

  // Remove step
  const handleRemoveStep = useCallback((index: number) => {
    setSteps(prev => prev.filter((_, i) => i !== index));
  }, []);

  // Move step up
  const handleMoveStepUp = useCallback((index: number) => {
    if (index === 0) return;
    setSteps(prev => {
      const newSteps = [...prev];
      [newSteps[index - 1], newSteps[index]] = [newSteps[index], newSteps[index - 1]];
      return newSteps;
    });
  }, []);

  // Move step down
  const handleMoveStepDown = useCallback((index: number) => {
    if (index === steps.length - 1) return;
    setSteps(prev => {
      const newSteps = [...prev];
      [newSteps[index], newSteps[index + 1]] = [newSteps[index + 1], newSteps[index]];
      return newSteps;
    });
  }, [steps.length]);

  // Validate and save
  const handleSave = async () => {
    setError(null);

    // Validation
    if (!name.trim()) {
      setError('请输入工作流名称');
      return;
    }

    if (steps.length === 0) {
      setError('请至少添加一个步骤');
      return;
    }

    const invalidSteps = steps.filter(s => !s.handName);
    if (invalidSteps.length > 0) {
      setError('所有步骤都必须选择一个 Hand');
      return;
    }

    try {
      await onSave({
        name: name.trim(),
        description: description.trim() || undefined,
        steps: steps.map(s => ({
          handName: s.handName,
          name: s.name,
          params: s.params,
          condition: s.condition,
        })),
      });
      onClose();
    } catch (err) {
      setError(err instanceof Error ? err.message : '保存失败');
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      {/* Backdrop */}
      <div
        className="absolute inset-0 bg-black/50 backdrop-blur-sm"
        onClick={onClose}
      />

      {/* Modal */}
      <div className="relative bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-full max-w-2xl mx-4 max-h-[90vh] overflow-hidden flex flex-col">
        {/* Header */}
        <div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 flex-shrink-0">
          <div className="flex items-center gap-3">
            <div className="w-8 h-8 bg-blue-100 dark:bg-blue-900/30 rounded-lg flex items-center justify-center">
              <GitBranch className="w-4 h-4 text-blue-600 dark:text-blue-400" />
            </div>
            <div>
              <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
                {isEditMode ? '编辑工作流' : '新建工作流'}
              </h2>
              {workflow && (
                <p className="text-sm text-gray-500 dark:text-gray-400">{workflow.name}</p>
              )}
            </div>
          </div>
          <button
            onClick={onClose}
            className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 p-1"
          >
            <X className="w-5 h-5" />
          </button>
        </div>

        {/* Body */}
        <div className="flex-1 overflow-y-auto p-4 space-y-4">
          {/* Error */}
          {error && (
            <div className="p-3 bg-red-50 dark:bg-red-900/20 rounded-lg border border-red-200 dark:border-red-800 text-red-700 dark:text-red-400 text-sm flex items-center gap-2">
              <AlertCircle className="w-4 h-4 flex-shrink-0" />
              {error}
            </div>
          )}

          {/* Basic Info */}
          <div className="space-y-3">
            <div>
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                工作流名称 *
              </label>
              <input
                type="text"
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="我的工作流"
                className="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
              />
            </div>

            <div>
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                描述
              </label>
              <textarea
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                placeholder="描述这个工作流的用途..."
                rows={2}
                className="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
              />
            </div>
          </div>

          {/* Steps */}
          <div>
            <div className="flex items-center justify-between mb-3">
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
                工作流步骤 ({steps.length})
              </label>
              <button
                onClick={handleAddStep}
                className="flex items-center gap-1 px-2 py-1 text-xs bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400 rounded-md hover:bg-blue-200 dark:hover:bg-blue-900/50"
              >
                <Plus className="w-3 h-3" />
                添加步骤
              </button>
            </div>

            {steps.length === 0 ? (
              <div className="p-8 text-center border-2 border-dashed border-gray-200 dark:border-gray-700 rounded-lg">
                <GitBranch className="w-8 h-8 mx-auto text-gray-300 dark:text-gray-600 mb-2" />
                <p className="text-sm text-gray-500 dark:text-gray-400 mb-2">
                  还没有添加步骤
                </p>
                <button
                  onClick={handleAddStep}
                  className="inline-flex items-center gap-1 px-3 py-1.5 text-sm bg-gray-700 dark:bg-gray-600 text-white rounded-lg hover:bg-gray-800 dark:hover:bg-gray-500"
                >
                  <Plus className="w-4 h-4" />
                  添加第一个步骤
                </button>
              </div>
            ) : (
              <div className="space-y-2">
                {steps.map((step, index) => (
                  <StepEditor
                    key={step.id}
                    step={step}
                    hands={hands}
                    index={index}
                    onUpdate={(s) => handleUpdateStep(index, s)}
                    onRemove={() => handleRemoveStep(index)}
                    onMoveUp={index > 0 ? () => handleMoveStepUp(index) : undefined}
                    onMoveDown={index < steps.length - 1 ? () => handleMoveStepDown(index) : undefined}
                  />
                ))}
              </div>
            )}
          </div>
        </div>

        {/* Footer */}
        <div className="flex items-center justify-end gap-2 p-4 border-t border-gray-200 dark:border-gray-700 flex-shrink-0">
          <button
            onClick={onClose}
            className="px-4 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300"
          >
            取消
          </button>
          <button
            onClick={handleSave}
            disabled={isSaving}
            className="px-4 py-2 text-sm bg-gray-700 dark:bg-gray-600 text-white rounded-lg hover:bg-gray-800 dark:hover:bg-gray-500 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
          >
            {isSaving ? (
              <>
                <Loader2 className="w-4 h-4 animate-spin" />
                保存中...
              </>
            ) : (
              <>
                <Save className="w-4 h-4" />
                保存工作流
              </>
            )}
          </button>
        </div>
      </div>
    </div>
  );
}

export default WorkflowEditor;
