'use client';

import { useState, useEffect, useCallback, useMemo } from 'react';
import { useParams } from 'next/navigation';
import Link from 'next/link';
import {
  ArrowLeft, Save, Plus, Trash2, ChevronUp, ChevronDown,
  Loader2, GitBranch, Play, Settings, AlertTriangle,
  CheckCircle, Pencil, X, Eye, Code
} from 'lucide-react';
import MermaidDiagram from '@/components/dark-factory/mermaid-diagram';

interface WorkflowStep {
  id: string;
  name: string;
  description: string | null;
  order: number;
  action: Record<string, unknown>;
  agentId: string | null;
  conditions: unknown;
  nextSteps: unknown;
  timeout: number | null;
  retryConfig: unknown;
}

interface Execution {
  id: string;
  status: string;
  currentStep: string | null;
  startedAt: string;
  completedAt: string | null;
}

interface Workflow {
  id: string;
  name: string;
  description: string | null;
  status: string;
  trigger: Record<string, unknown>;
  createdAt: string;
  workflowSteps: WorkflowStep[];
  WorkflowExecution: Execution[];
}

function buildMermaidFromSteps(steps: WorkflowStep[]): string {
  if (steps.length === 0) return 'graph TD\n  empty[No steps defined]';

  const lines: string[] = ['graph TD'];
  const sanitize = (s: string) => s.replace(/["'\[\]\(\){}]/g, ' ').trim();

  // Start node
  lines.push('  START(("\u25B6 Start"))');

  // Step nodes
  steps.forEach((step, i) => {
    const nodeId = `S${i}`;
    const actionType = step.action?.type ? String(step.action.type) : 'task';
    const label = sanitize(step.name);
    const desc = step.description ? `<br/><small>${sanitize(step.description).slice(0, 60)}</small>` : '';

    // Shape based on action type
    if (actionType === 'condition' || actionType === 'gate') {
      lines.push(`  ${nodeId}{"${label}${desc}"}`);
    } else if (actionType === 'notification' || actionType === 'alert') {
      lines.push(`  ${nodeId}(["${label}${desc}"])`);
    } else {
      lines.push(`  ${nodeId}["${label}${desc}"]`);
    }
  });

  // End node
  lines.push('  END(("\u2713 End"))');

  // Edges
  if (steps.length > 0) {
    lines.push(`  START --> S0`);
  }
  steps.forEach((step, i) => {
    // Check for conditional branching via nextSteps
    const nextStepsArr = Array.isArray(step.nextSteps) ? step.nextSteps as Array<{ label?: string; stepIndex?: number }> : null;
    if (nextStepsArr && nextStepsArr.length > 0) {
      nextStepsArr.forEach(ns => {
        const targetIdx = ns.stepIndex ?? (i + 1);
        const target = targetIdx < steps.length ? `S${targetIdx}` : 'END';
        const edgeLabel = ns.label ? `|"${sanitize(ns.label)}"|` : '';
        lines.push(`  S${i} -->${edgeLabel} ${target}`);
      });
    } else if (i < steps.length - 1) {
      lines.push(`  S${i} --> S${i + 1}`);
    } else {
      lines.push(`  S${i} --> END`);
    }
  });

  // Styling
  lines.push('  style START fill:#10b981,stroke:#059669,color:#fff');
  lines.push('  style END fill:#10b981,stroke:#059669,color:#fff');
  steps.forEach((step, i) => {
    const actionType = step.action?.type ? String(step.action.type) : 'task';
    if (actionType === 'condition' || actionType === 'gate') {
      lines.push(`  style S${i} fill:#f59e0b,stroke:#d97706,color:#fff`);
    } else if (actionType === 'notification' || actionType === 'alert') {
      lines.push(`  style S${i} fill:#FDBA74,stroke:#FB923C,color:#fff`);
    } else {
      lines.push(`  style S${i} fill:#3b82f6,stroke:#2563eb,color:#fff`);
    }
  });

  return lines.join('\n');
}

export default function WorkflowEditorPage() {
  const params = useParams();
  const [workflow, setWorkflow] = useState<Workflow | null>(null);
  const [steps, setSteps] = useState<WorkflowStep[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');
  const [editingStep, setEditingStep] = useState<number | null>(null);
  const [editStepData, setEditStepData] = useState<Record<string, unknown>>({});
  const [viewMode, setViewMode] = useState<'diagram' | 'split'>('split');
  const [hasChanges, setHasChanges] = useState(false);

  const fetchWorkflow = useCallback(async () => {
    try {
      const res = await fetch(`/api/dark-factory/workflows/${params.id}`);
      const data = await res.json();
      if (data.workflow) {
        setWorkflow(data.workflow);
        setSteps(data.workflow.workflowSteps || []);
      } else setError('Workflow not found');
    } catch { setError('Failed to load workflow'); }
    setLoading(false);
  }, [params.id]);

  useEffect(() => { fetchWorkflow(); }, [fetchWorkflow]);

  const mermaidCode = useMemo(() => buildMermaidFromSteps(steps), [steps]);

  const handleAddStep = () => {
    const newStep: WorkflowStep = {
      id: `new-${Date.now()}`,
      name: `Step ${steps.length + 1}`,
      description: null,
      order: steps.length,
      action: { type: 'task' },
      agentId: null,
      conditions: null,
      nextSteps: null,
      timeout: null,
      retryConfig: null,
    };
    setSteps([...steps, newStep]);
    setHasChanges(true);
    setEditingStep(steps.length);
    setEditStepData({
      name: newStep.name,
      description: '',
      actionType: 'task',
      actionCommand: '',
      timeout: '',
    });
  };

  const handleRemoveStep = (index: number) => {
    setSteps(prev => prev.filter((_, i) => i !== index).map((s, i) => ({ ...s, order: i })));
    setHasChanges(true);
    if (editingStep === index) setEditingStep(null);
    else if (editingStep !== null && editingStep > index) setEditingStep(editingStep - 1);
  };

  const handleMoveStep = (index: number, direction: 'up' | 'down') => {
    const newSteps = [...steps];
    const targetIdx = direction === 'up' ? index - 1 : index + 1;
    if (targetIdx < 0 || targetIdx >= newSteps.length) return;
    [newSteps[index], newSteps[targetIdx]] = [newSteps[targetIdx], newSteps[index]];
    newSteps.forEach((s, i) => s.order = i);
    setSteps(newSteps);
    setHasChanges(true);
    if (editingStep === index) setEditingStep(targetIdx);
    else if (editingStep === targetIdx) setEditingStep(index);
  };

  const startEditStep = (index: number) => {
    const step = steps[index];
    setEditingStep(index);
    setEditStepData({
      name: step.name,
      description: step.description || '',
      actionType: step.action?.type || 'task',
      actionCommand: step.action?.command || step.action?.url || '',
      timeout: step.timeout || '',
    });
  };

  const saveStepEdit = () => {
    if (editingStep === null) return;
    setSteps(prev => prev.map((s, i) => {
      if (i !== editingStep) return s;
      return {
        ...s,
        name: (editStepData.name as string) || s.name,
        description: (editStepData.description as string) || null,
        action: {
          type: (editStepData.actionType as string) || 'task',
          command: (editStepData.actionCommand as string) || undefined,
        },
        timeout: editStepData.timeout ? Number(editStepData.timeout) : null,
      };
    }));
    setHasChanges(true);
    setEditingStep(null);
  };

  const handleSave = async () => {
    setSaving(true);
    setError('');
    setSuccess('');
    try {
      const res = await fetch(`/api/dark-factory/workflows/${params.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          steps: steps.map(s => ({
            name: s.name,
            description: s.description,
            action: s.action,
            agentId: s.agentId,
            conditions: s.conditions,
            nextSteps: s.nextSteps,
            timeout: s.timeout,
            retryConfig: s.retryConfig,
          })),
        }),
      });
      if (res.ok) {
        const data = await res.json();
        setWorkflow(data.workflow);
        setSteps(data.workflow.workflowSteps || []);
        setHasChanges(false);
        setSuccess('Workflow saved successfully');
        setTimeout(() => setSuccess(''), 3000);
      } else {
        const d = await res.json();
        setError(d.error || 'Save failed');
      }
    } catch { setError('Save failed'); }
    setSaving(false);
  };

  if (loading) return <div className="text-center py-16 text-gray-500">Loading workflow...</div>;
  if (!workflow) return <div className="text-center py-16 text-red-400">{error || 'Not found'}</div>;

  const triggerType = typeof workflow.trigger === 'object' && workflow.trigger !== null
    ? (workflow.trigger as Record<string, string>).type || 'manual'
    : 'manual';

  return (
    <div className="space-y-6 max-w-6xl mx-auto">
      {/* Header */}
      <div className="flex items-start gap-3">
        <Link href="/dark-factory/app/workflows" className="text-gray-400 hover:text-white mt-1"><ArrowLeft className="w-5 h-5" /></Link>
        <div className="flex-1">
          <h1 className="text-2xl font-bold text-white flex items-center gap-2">
            <GitBranch className="w-6 h-6 text-sky-400" />
            {workflow.name}
          </h1>
          {workflow.description && <p className="text-gray-400 text-sm mt-1">{workflow.description}</p>}
          <div className="flex items-center gap-3 mt-2 text-xs text-gray-500">
            <span>Status: <span className={workflow.status === 'active' ? 'text-green-400' : 'text-gray-400'}>{workflow.status}</span></span>
            <span>·</span>
            <span>Trigger: {triggerType}</span>
            <span>·</span>
            <span>{steps.length} steps</span>
            <span>·</span>
            <span>{workflow.WorkflowExecution.length} recent runs</span>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => setViewMode(viewMode === 'diagram' ? 'split' : 'diagram')}
            className={`p-2 rounded-lg text-sm ${viewMode === 'diagram' ? 'bg-sky-500/20 text-sky-400' : 'bg-slate-800 text-gray-400 hover:text-white'}`}
            title={viewMode === 'diagram' ? 'Show editor' : 'Diagram only'}
          >
            {viewMode === 'diagram' ? <Settings className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
          </button>
          <button
            onClick={handleSave}
            disabled={!hasChanges || saving}
            className="flex items-center gap-2 px-4 py-2 bg-green-600 hover:bg-green-700 disabled:opacity-50 text-white rounded-lg text-sm font-medium"
          >
            {saving ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />}
            Save
          </button>
        </div>
      </div>

      {error && <div className="p-3 bg-red-500/10 border border-red-500/30 rounded-lg text-red-400 text-sm">{error} <button onClick={() => setError('')} className="ml-2 underline">dismiss</button></div>}
      {success && <div className="p-3 bg-green-500/10 border border-green-500/30 rounded-lg text-green-400 text-sm">{success}</div>}
      {hasChanges && <div className="p-2 bg-amber-500/10 border border-amber-500/20 rounded-lg text-amber-400 text-xs text-center">Unsaved changes — click Save to persist</div>}

      {/* Main Content: Diagram + Editor */}
      <div className={viewMode === 'split' ? 'grid lg:grid-cols-2 gap-4' : ''}>
        {/* Mermaid Diagram */}
        <div className={viewMode === 'diagram' ? '' : ''}>
          <div className="bg-slate-900 border border-slate-700 rounded-xl overflow-hidden">
            <div className="px-4 py-2 bg-slate-800/50 border-b border-slate-700/30 flex items-center gap-2">
              <GitBranch className="w-4 h-4 text-sky-400" />
              <span className="text-sm font-medium text-white">Flow Diagram</span>
              <span className="text-[10px] text-gray-500 ml-auto">Auto-generated from steps</span>
            </div>
            <MermaidDiagram code={mermaidCode} title={workflow.name} />
          </div>
        </div>

        {/* Step Editor Panel */}
        {viewMode === 'split' && (
          <div className="space-y-3">
            <div className="flex items-center justify-between">
              <h3 className="text-sm font-semibold text-white">Workflow Steps</h3>
              <button onClick={handleAddStep}
                className="flex items-center gap-1 px-3 py-1.5 bg-sky-600 hover:bg-sky-700 text-white rounded-lg text-xs font-medium">
                <Plus className="w-3 h-3" /> Add Step
              </button>
            </div>

            {steps.length === 0 ? (
              <div className="text-center py-8 border border-dashed border-slate-700 rounded-xl">
                <p className="text-gray-500 text-sm">No steps yet. Add a step to build the workflow.</p>
              </div>
            ) : (
              <div className="space-y-2">
                {steps.map((step, i) => (
                  <div key={step.id} className={`bg-slate-900 border rounded-lg overflow-hidden transition-colors ${
                    editingStep === i ? 'border-sky-500/50' : 'border-slate-700'
                  }`}>
                    <div className="flex items-center gap-2 px-3 py-2">
                      <span className="text-[10px] font-mono text-gray-600 w-5 text-center">{i + 1}</span>
                      <div className={`w-2 h-2 rounded-full ${
                        (step.action?.type === 'condition' || step.action?.type === 'gate') ? 'bg-amber-400' :
                        (step.action?.type === 'notification') ? 'bg-orange-400' : 'bg-blue-400'
                      }`} />
                      <div className="flex-1 min-w-0">
                        <span className="text-white text-sm font-medium">{step.name}</span>
                        {step.description && <span className="text-gray-500 text-xs ml-2">— {step.description}</span>}
                      </div>
                      <div className="flex items-center gap-1">
                        <button onClick={() => handleMoveStep(i, 'up')} disabled={i === 0}
                          className="p-1 text-gray-600 hover:text-white disabled:opacity-30"><ChevronUp className="w-3 h-3" /></button>
                        <button onClick={() => handleMoveStep(i, 'down')} disabled={i === steps.length - 1}
                          className="p-1 text-gray-600 hover:text-white disabled:opacity-30"><ChevronDown className="w-3 h-3" /></button>
                        <button onClick={() => editingStep === i ? setEditingStep(null) : startEditStep(i)}
                          className={`p-1 ${editingStep === i ? 'text-sky-400' : 'text-gray-600 hover:text-white'}`}>
                          {editingStep === i ? <X className="w-3 h-3" /> : <Pencil className="w-3 h-3" />}
                        </button>
                        <button onClick={() => handleRemoveStep(i)}
                          className="p-1 text-gray-600 hover:text-red-400"><Trash2 className="w-3 h-3" /></button>
                      </div>
                    </div>

                    {/* Inline edit form */}
                    {editingStep === i && (
                      <div className="px-3 pb-3 pt-1 border-t border-slate-700/50 space-y-2">
                        <div>
                          <label className="block text-[10px] text-gray-500 mb-0.5">Step Name</label>
                          <input className="w-full bg-slate-800 border border-slate-600 rounded px-2 py-1.5 text-white text-xs"
                            value={(editStepData.name as string) || ''}
                            onChange={e => setEditStepData(d => ({ ...d, name: e.target.value }))} />
                        </div>
                        <div>
                          <label className="block text-[10px] text-gray-500 mb-0.5">Description</label>
                          <input className="w-full bg-slate-800 border border-slate-600 rounded px-2 py-1.5 text-white text-xs"
                            value={(editStepData.description as string) || ''}
                            onChange={e => setEditStepData(d => ({ ...d, description: e.target.value }))} />
                        </div>
                        <div className="grid grid-cols-2 gap-2">
                          <div>
                            <label className="block text-[10px] text-gray-500 mb-0.5">Action Type</label>
                            <select className="w-full bg-slate-800 border border-slate-600 rounded px-2 py-1.5 text-white text-xs"
                              value={(editStepData.actionType as string) || 'task'}
                              onChange={e => setEditStepData(d => ({ ...d, actionType: e.target.value }))}>
                              <option value="task">Task</option>
                              <option value="condition">Condition/Gate</option>
                              <option value="notification">Notification</option>
                              <option value="api_call">API Call</option>
                              <option value="data_transform">Data Transform</option>
                              <option value="approval">Human Approval</option>
                            </select>
                          </div>
                          <div>
                            <label className="block text-[10px] text-gray-500 mb-0.5">Timeout (sec)</label>
                            <input type="number" className="w-full bg-slate-800 border border-slate-600 rounded px-2 py-1.5 text-white text-xs"
                              value={(editStepData.timeout as string) || ''}
                              onChange={e => setEditStepData(d => ({ ...d, timeout: e.target.value }))} />
                          </div>
                        </div>
                        <div>
                          <label className="block text-[10px] text-gray-500 mb-0.5">Command / URL</label>
                          <input className="w-full bg-slate-800 border border-slate-600 rounded px-2 py-1.5 text-white text-xs"
                            value={(editStepData.actionCommand as string) || ''}
                            placeholder="e.g. /api/process or custom command"
                            onChange={e => setEditStepData(d => ({ ...d, actionCommand: e.target.value }))} />
                        </div>
                        <div className="flex justify-end gap-2 pt-1">
                          <button onClick={() => setEditingStep(null)} className="px-3 py-1 text-xs text-gray-400 hover:text-white">Cancel</button>
                          <button onClick={saveStepEdit} className="px-3 py-1 bg-sky-600 hover:bg-sky-700 text-white rounded text-xs">Apply</button>
                        </div>
                      </div>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
      </div>

      {/* Mermaid Source Code */}
      <div className="bg-slate-900 border border-slate-700 rounded-xl p-4">
        <div className="flex items-center gap-2 mb-2">
          <Code className="w-4 h-4 text-gray-500" />
          <span className="text-sm font-medium text-gray-400">Generated Mermaid Source</span>
        </div>
        <pre className="text-xs text-gray-500 font-mono whitespace-pre-wrap bg-slate-950 rounded-lg p-3 max-h-[200px] overflow-auto">{mermaidCode}</pre>
      </div>

      {/* Recent Executions */}
      {workflow.WorkflowExecution.length > 0 && (
        <div className="bg-slate-900 border border-slate-700 rounded-xl p-5">
          <h3 className="text-sm font-semibold text-white mb-3 flex items-center gap-2"><Play className="w-4 h-4 text-green-400" /> Recent Executions</h3>
          <div className="space-y-2">
            {workflow.WorkflowExecution.map(exec => (
              <div key={exec.id} className="flex items-center gap-3 text-sm">
                <div className={`w-2 h-2 rounded-full ${
                  exec.status === 'completed' ? 'bg-green-400' :
                  exec.status === 'running' ? 'bg-blue-400 animate-pulse' :
                  exec.status === 'failed' ? 'bg-red-400' : 'bg-gray-400'
                }`} />
                <span className="text-gray-300">{exec.status}</span>
                {exec.currentStep && <span className="text-gray-500 text-xs">— at: {exec.currentStep}</span>}
                <span className="text-gray-600 text-xs ml-auto">{new Date(exec.startedAt).toLocaleDateString()}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}
