'use client';

import { useState, useRef } from 'react';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
  Variable,
  Plus,
  Trash2,
  GripVertical,
  ChevronDown,
  Copy,
} from 'lucide-react';

// ============================================================================
// Available fields per trigger source
// ============================================================================

const TRIGGER_FIELDS: Record<string, { key: string; label: string; group: string }[]> = {
  datto_rmm: [
    { key: 'triggered', label: 'Triggered (True/False)', group: 'Alert' },
    { key: 'alert_type', label: 'Alert Type', group: 'Alert' },
    { key: 'alert_category', label: 'Alert Category', group: 'Alert' },
    { key: 'alert_priority', label: 'Alert Priority', group: 'Alert' },
    { key: 'alert_message_en', label: 'Alert Message', group: 'Alert' },
    { key: 'alert_uid', label: 'Alert UID', group: 'Alert' },
    { key: 'device_hostname', label: 'Device Hostname', group: 'Device' },
    { key: 'device_id', label: 'Device ID', group: 'Device' },
    { key: 'device_uid', label: 'Device UID', group: 'Device' },
    { key: 'device_ip', label: 'Device IP', group: 'Device' },
    { key: 'device_os', label: 'Device OS', group: 'Device' },
    { key: 'device_description', label: 'Device Description', group: 'Device' },
    { key: 'last_user', label: 'Last User', group: 'Device' },
    { key: 'site_name', label: 'Site Name', group: 'Site' },
    { key: 'site_id', label: 'Site ID', group: 'Site' },
    { key: 'site_uid', label: 'Site UID', group: 'Site' },
    { key: 'platform', label: 'Platform', group: 'Site' },
    ...Array.from({ length: 29 }, (_, i) => ({
      key: `device_udf${i + 1}`, label: `UDF ${i + 1}`, group: 'UDF',
    })),
  ],
  autotask: [
    { key: 'Action', label: 'Action (Create/Update/Delete)', group: 'Event' },
    { key: 'EntityType', label: 'Entity Type', group: 'Event' },
    { key: 'Id', label: 'Entity ID', group: 'Event' },
    { key: 'EventTime', label: 'Event Time', group: 'Event' },
    { key: 'SequenceNumber', label: 'Sequence Number', group: 'Event' },
    { key: 'PersonId', label: 'Person ID', group: 'Event' },
  ],
  veeam: [
    { key: 'eventType', label: 'Event Type', group: 'Event' },
    { key: 'severity', label: 'Severity', group: 'Event' },
    { key: 'message', label: 'Message', group: 'Event' },
  ],
  manual: [],
};

// Fields produced by enrichment steps
const STEP_OUTPUT_FIELDS: Record<string, { key: string; label: string }[]> = {
  enrich_device: [
    { key: 'device_found', label: 'Device Found (bool)' },
    { key: 'device_hostname', label: 'Device Hostname' },
    { key: 'device_os', label: 'Device OS' },
    { key: 'device_ip', label: 'Device IP' },
    { key: 'company_id', label: 'Company ID' },
    { key: 'company_name', label: 'Company Name' },
  ],
  enrich_company: [
    { key: 'company_found', label: 'Company Found (bool)' },
    { key: 'company_id', label: 'Company ID' },
    { key: 'company_name', label: 'Company Name' },
  ],
  enrich_ticket: [
    { key: 'ticket_found', label: 'Ticket Found (bool)' },
    { key: 'ticket_id', label: 'Ticket ID' },
    { key: 'ticket_number', label: 'Ticket Number' },
    { key: 'ticket_title', label: 'Ticket Title' },
  ],
  transform: [], // dynamic — comes from mappings
  set_variable: [], // dynamic
  create_ticket: [
    { key: 'ticket_id', label: 'Created Ticket ID' },
    { key: 'ticket_number', label: 'Created Ticket Number' },
  ],
  ai_analyze: [
    { key: 'ai_response', label: 'AI Response' },
    { key: 'ai_provider', label: 'AI Provider' },
    { key: 'ai_model', label: 'AI Model' },
  ],
  approval: [
    { key: 'approval_id', label: 'Approval ID' },
    { key: 'approval_result', label: 'Approval Result' },
  ],
  rmm_quick_job: [
    { key: 'job_uid', label: 'Job UID' },
    { key: 'quick_job_result', label: 'Job Result' },
  ],
  rmm_get_job_results: [
    { key: 'job_results', label: 'Job Results' },
    { key: 'job_status', label: 'Job Status' },
  ],
  notify: [{ key: 'notified', label: 'Notified (bool)' }],
  enrich_vspc: [
    { key: 'vspc_found', label: 'VSPC Found (bool)' },
    { key: 'vspc_last_job_status', label: 'Last Job Status' },
    { key: 'vspc_last_success', label: 'Last Success Date' },
    { key: 'vspc_hours_since_success', label: 'Hours Since Success' },
    { key: 'vspc_failure_message', label: 'Failure Message' },
    { key: 'vspc_restore_points', label: 'Restore Points' },
    { key: 'vspc_backed_up_size', label: 'Backed Up Size' },
    { key: 'vspc_alarm_count', label: 'Alarm Count' },
    { key: 'vspc_failed_job_count', label: 'Failed Job Count' },
    { key: 'vspc_summary', label: 'VSPC Summary Text' },
    { key: 'vspc_agent_jobs', label: 'Agent Jobs (array)' },
    { key: 'vspc_server_jobs', label: 'Server Jobs (array)' },
    { key: 'vspc_workloads', label: 'Workloads (array)' },
    { key: 'vspc_alarms', label: 'Alarms (array)' },
  ],
  db_query: [], // dynamic — output_key from config
  fetch_b2_result: [], // dynamic — output_key from config
};

// Autotask ticket fields for create_ticket
const TICKET_FIELDS = [
  { key: 'title', label: 'Title', required: true, type: 'text' as const },
  { key: 'description', label: 'Description', required: false, type: 'textarea' as const },
  { key: 'companyID', label: 'Company ID', required: true, type: 'variable' as const },
  { key: 'ticketType', label: 'Ticket Type', required: false, type: 'select' as const, options: [
    { value: '1', label: '1 — Service Request' },
    { value: '2', label: '2 — Incident' },
    { value: '3', label: '3 — Problem' },
    { value: '4', label: '4 — Change Request' },
  ]},
  { key: 'priority', label: 'Priority', required: false, type: 'select' as const, options: [
    { value: '1', label: '1 — Critical' },
    { value: '2', label: '2 — High' },
    { value: '3', label: '3 — Medium' },
    { value: '4', label: '4 — Low' },
  ]},
  { key: 'status', label: 'Status', required: false, type: 'select' as const, options: [
    { value: '1', label: '1 — New' },
    { value: '5', label: '5 — In Progress' },
  ]},
  { key: 'queueID', label: 'Queue ID', required: false, type: 'text' as const },
  { key: 'issueType', label: 'Issue Type ID', required: false, type: 'text' as const },
  { key: 'subIssueType', label: 'Sub-Issue Type ID', required: false, type: 'text' as const },
  { key: 'ticketCategory', label: 'Ticket Category', required: false, type: 'select' as const, options: [
    { value: '3', label: '3 — Standard' },
  ]},
];

// ============================================================================
// Props
// ============================================================================

interface StepConfigEditorProps {
  stepType: string;
  config: Record<string, any>;
  triggerSource: string;
  priorSteps: { step_type: string; name: string; config: Record<string, any> }[];
  channels: { id: number; name: string; channel_type: string }[];
  onChange: (config: Record<string, any>) => void;
}

// ============================================================================
// Variable Picker — shows insertable {{variables}} from trigger + prior steps
// ============================================================================

function VariablePicker({
  triggerSource,
  priorSteps,
  onInsert,
  compact = false,
}: {
  triggerSource: string;
  priorSteps: { step_type: string; name: string; config: Record<string, any> }[];
  onInsert: (variable: string) => void;
  compact?: boolean;
}) {
  const [isOpen, setIsOpen] = useState(false);
  const triggerFields = TRIGGER_FIELDS[triggerSource] || [];

  // Gather context fields from prior steps
  const contextFields: { key: string; label: string; source: string }[] = [];
  for (const step of priorSteps) {
    const outputs = STEP_OUTPUT_FIELDS[step.step_type] || [];
    for (const f of outputs) {
      contextFields.push({ ...f, source: step.name });
    }
    // For transform steps, add the mapping keys
    if (step.step_type === 'transform' && step.config.mappings) {
      for (const key of Object.keys(step.config.mappings)) {
        contextFields.push({ key, label: key, source: step.name });
      }
    }
    // For set_variable, add the key
    if (step.step_type === 'set_variable' && step.config.key) {
      contextFields.push({ key: step.config.key, label: step.config.key, source: step.name });
    }
  }

  // Group trigger fields
  const triggerGroups = new Map<string, typeof triggerFields>();
  for (const f of triggerFields) {
    const group = triggerGroups.get(f.group) || [];
    group.push(f);
    triggerGroups.set(f.group, group);
  }

  if (!isOpen) {
    return (
      <Button
        variant="outline"
        size={compact ? 'sm' : 'default'}
        className={compact ? 'h-7 text-xs px-2' : ''}
        onClick={() => setIsOpen(true)}
      >
        <Variable className="h-3 w-3 mr-1" />
        Insert Variable
      </Button>
    );
  }

  return (
    <div className="border rounded-lg bg-background shadow-lg p-3 space-y-3 max-h-80 overflow-y-auto">
      <div className="flex items-center justify-between">
        <span className="text-xs font-semibold text-muted-foreground uppercase">Insert Variable</span>
        <Button variant="ghost" size="sm" className="h-6 text-xs" onClick={() => setIsOpen(false)}>Close</Button>
      </div>

      {/* Trigger fields */}
      {triggerFields.length > 0 && (
        <div>
          <div className="text-xs font-semibold text-muted-foreground mb-1">Trigger Payload</div>
          {Array.from(triggerGroups.entries()).map(([group, fields]) => (
            <div key={group} className="mb-2">
              <div className="text-[10px] uppercase text-muted-foreground/60 mb-0.5">{group}</div>
              <div className="flex flex-wrap gap-1">
                {fields.map(f => (
                  <button
                    key={f.key}
                    className="px-1.5 py-0.5 text-[11px] bg-blue-50 hover:bg-blue-100 text-blue-700 rounded border border-blue-200 cursor-pointer transition-colors"
                    onClick={() => { onInsert(`{{trigger.${f.key}}}`); setIsOpen(false); }}
                    title={`{{trigger.${f.key}}}`}
                  >
                    {f.label}
                  </button>
                ))}
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Context fields from prior steps */}
      {contextFields.length > 0 && (
        <div>
          <div className="text-xs font-semibold text-muted-foreground mb-1">From Prior Steps</div>
          <div className="flex flex-wrap gap-1">
            {contextFields.map((f, i) => (
              <button
                key={`${f.key}-${i}`}
                className="px-1.5 py-0.5 text-[11px] bg-green-50 hover:bg-green-100 text-green-700 rounded border border-green-200 cursor-pointer transition-colors"
                onClick={() => { onInsert(`{{context.${f.key}}}`); setIsOpen(false); }}
                title={`{{context.${f.key}}} — from "${f.source}"`}
              >
                {f.label}
                <span className="text-[9px] text-green-500 ml-1">({f.source})</span>
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

// ============================================================================
// Insertable Input — text input with variable insert button
// ============================================================================

function InsertableInput({
  value,
  onChange,
  placeholder,
  triggerSource,
  priorSteps,
  multiline = false,
  rows = 3,
  label,
  required = false,
}: {
  value: string;
  onChange: (val: string) => void;
  placeholder?: string;
  triggerSource: string;
  priorSteps: { step_type: string; name: string; config: Record<string, any> }[];
  multiline?: boolean;
  rows?: number;
  label?: string;
  required?: boolean;
}) {
  const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);

  const handleInsert = (variable: string) => {
    const el = inputRef.current;
    if (el) {
      const start = el.selectionStart || value.length;
      const end = el.selectionEnd || value.length;
      const newVal = value.substring(0, start) + variable + value.substring(end);
      onChange(newVal);
      // Restore cursor after the inserted variable
      setTimeout(() => {
        el.focus();
        el.setSelectionRange(start + variable.length, start + variable.length);
      }, 0);
    } else {
      onChange(value + variable);
    }
  };

  return (
    <div className="space-y-1">
      {label && (
        <div className="flex items-center justify-between">
          <label className="text-xs font-medium text-muted-foreground">
            {label} {required && <span className="text-red-400">*</span>}
          </label>
          <VariablePicker triggerSource={triggerSource} priorSteps={priorSteps} onInsert={handleInsert} compact />
        </div>
      )}
      {multiline ? (
        <textarea
          ref={inputRef as any}
          className="w-full px-2.5 py-1.5 text-sm border rounded bg-background font-mono"
          rows={rows}
          placeholder={placeholder}
          value={value}
          onChange={e => onChange(e.target.value)}
        />
      ) : (
        <input
          ref={inputRef as any}
          className="w-full px-2.5 py-1.5 text-sm border rounded bg-background"
          placeholder={placeholder}
          value={value}
          onChange={e => onChange(e.target.value)}
        />
      )}
      {/* Show resolved variable badges */}
      {value && value.includes('{{') && (
        <div className="flex flex-wrap gap-1">
          {(value.match(/\{\{[^}]+\}\}/g) || []).map((v, i) => (
            <Badge key={i} variant="outline" className="text-[10px] bg-violet-50 text-violet-600 border-violet-200">
              {v}
            </Badge>
          ))}
        </div>
      )}
    </div>
  );
}

// ============================================================================
// Step-specific editors
// ============================================================================

function TransformEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  const mappings: Record<string, string> = config.mappings || {};
  const keys = Object.keys(mappings);
  const [newKey, setNewKey] = useState('');

  const triggerFields = TRIGGER_FIELDS[triggerSource] || [];

  const updateMapping = (key: string, value: string) => {
    onChange({ ...config, mappings: { ...mappings, [key]: value } });
  };

  const removeMapping = (key: string) => {
    const updated = { ...mappings };
    delete updated[key];
    onChange({ ...config, mappings: updated });
  };

  const addMapping = (fieldKey: string) => {
    onChange({ ...config, mappings: { ...mappings, [fieldKey]: `{{trigger.${fieldKey}}}` } });
  };

  const addCustomMapping = () => {
    if (!newKey) return;
    onChange({ ...config, mappings: { ...mappings, [newKey]: '' } });
    setNewKey('');
  };

  // Fields not yet extracted
  const availableFields = triggerFields.filter(f => !mappings[f.key]);
  const groups = new Map<string, typeof availableFields>();
  for (const f of availableFields) {
    const g = groups.get(f.group) || [];
    g.push(f);
    groups.set(f.group, g);
  }

  return (
    <div className="space-y-4">
      {/* Current mappings */}
      {keys.length > 0 && (
        <div className="space-y-2">
          <div className="text-xs font-semibold text-muted-foreground">Extracted Fields</div>
          {keys.map(key => (
            <div key={key} className="flex items-center gap-2 bg-muted/50 rounded p-2">
              <Badge variant="outline" className="font-mono text-xs shrink-0">{key}</Badge>
              <span className="text-muted-foreground text-xs">=</span>
              <input
                className="flex-1 px-2 py-1 text-xs border rounded bg-background font-mono"
                value={mappings[key]}
                onChange={e => updateMapping(key, e.target.value)}
              />
              <Button variant="ghost" size="icon" className="h-6 w-6 shrink-0" onClick={() => removeMapping(key)}>
                <Trash2 className="h-3 w-3 text-red-400" />
              </Button>
            </div>
          ))}
        </div>
      )}

      {/* Available fields to extract */}
      <div>
        <div className="text-xs font-semibold text-muted-foreground mb-2">Available Fields — click to extract</div>
        {Array.from(groups.entries()).map(([group, fields]) => (
          <div key={group} className="mb-2">
            <div className="text-[10px] uppercase text-muted-foreground/60 mb-1">{group}</div>
            <div className="flex flex-wrap gap-1">
              {fields.map(f => (
                <button
                  key={f.key}
                  className="px-2 py-1 text-xs bg-blue-50 hover:bg-blue-100 text-blue-700 rounded border border-blue-200 cursor-pointer transition-colors"
                  onClick={() => addMapping(f.key)}
                  title={`Extract {{trigger.${f.key}}} as context.${f.key}`}
                >
                  <Plus className="h-2.5 w-2.5 inline mr-0.5" />
                  {f.label}
                </button>
              ))}
            </div>
          </div>
        ))}
      </div>

      {/* Custom field */}
      <div className="flex gap-2">
        <input
          className="flex-1 px-2.5 py-1.5 text-sm border rounded bg-background"
          placeholder="Custom field name..."
          value={newKey}
          onChange={e => setNewKey(e.target.value)}
          onKeyDown={e => e.key === 'Enter' && addCustomMapping()}
        />
        <Button variant="outline" size="sm" onClick={addCustomMapping} disabled={!newKey}>
          <Plus className="h-3 w-3 mr-1" /> Add Custom
        </Button>
      </div>
    </div>
  );
}

function FilterEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  const conditions: any[] = config.conditions || [];

  const addCondition = () => {
    onChange({ ...config, conditions: [...conditions, { field: '', operator: 'equals', value: '' }] });
  };

  const updateCondition = (index: number, updates: any) => {
    const updated = conditions.map((c, i) => i === index ? { ...c, ...updates } : c);
    onChange({ ...config, conditions: updated });
  };

  const removeCondition = (index: number) => {
    onChange({ ...config, conditions: conditions.filter((_, i) => i !== index) });
  };

  const allFields = [
    ...(TRIGGER_FIELDS[triggerSource] || []).map(f => ({ key: `trigger.${f.key}`, label: `Trigger: ${f.label}` })),
    ...getContextFields(priorSteps).map(f => ({ key: `context.${f.key}`, label: `Context: ${f.label}` })),
  ];

  return (
    <div className="space-y-3">
      <div className="text-xs font-semibold text-muted-foreground">Conditions (all must match)</div>
      {conditions.map((cond, i) => (
        <div key={i} className="flex items-center gap-2 bg-muted/50 rounded p-2">
          <select
            className="px-2 py-1 text-xs border rounded bg-background min-w-[180px]"
            value={cond.field}
            onChange={e => updateCondition(i, { field: e.target.value })}
          >
            <option value="">Select field...</option>
            {allFields.map(f => <option key={f.key} value={f.key}>{f.label}</option>)}
          </select>
          <select
            className="px-2 py-1 text-xs border rounded bg-background"
            value={cond.operator}
            onChange={e => updateCondition(i, { operator: e.target.value })}
          >
            <option value="equals">equals</option>
            <option value="not_equals">not equals</option>
            <option value="contains">contains</option>
            <option value="not_contains">not contains</option>
            <option value="regex">regex</option>
            <option value="exists">exists</option>
            <option value="not_exists">not exists</option>
          </select>
          {!['exists', 'not_exists'].includes(cond.operator) && (
            <input
              className="flex-1 px-2 py-1 text-xs border rounded bg-background"
              placeholder="Value..."
              value={cond.value}
              onChange={e => updateCondition(i, { value: e.target.value })}
            />
          )}
          <Button variant="ghost" size="icon" className="h-6 w-6 shrink-0" onClick={() => removeCondition(i)}>
            <Trash2 className="h-3 w-3 text-red-400" />
          </Button>
        </div>
      ))}
      <Button variant="outline" size="sm" onClick={addCondition}>
        <Plus className="h-3 w-3 mr-1" /> Add Condition
      </Button>
    </div>
  );
}

function CreateTicketEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  const template: Record<string, any> = config.template || {};

  const updateField = (key: string, value: string) => {
    onChange({ ...config, template: { ...template, [key]: value } });
  };

  return (
    <div className="space-y-3">
      <div className="text-xs font-semibold text-muted-foreground">Ticket Fields</div>
      {TICKET_FIELDS.map(field => (
        <div key={field.key}>
          {field.type === 'select' ? (
            <div className="space-y-1">
              <label className="text-xs font-medium text-muted-foreground">
                {field.label} {field.required && <span className="text-red-400">*</span>}
              </label>
              <div className="flex gap-2">
                <select
                  className="flex-1 px-2.5 py-1.5 text-sm border rounded bg-background"
                  value={template[field.key] || ''}
                  onChange={e => updateField(field.key, e.target.value)}
                >
                  <option value="">— Select —</option>
                  {field.options?.map(opt => (
                    <option key={opt.value} value={opt.value}>{opt.label}</option>
                  ))}
                </select>
                {/* Allow typing a variable instead */}
                <input
                  className="w-48 px-2 py-1 text-xs border rounded bg-background font-mono"
                  placeholder="or {{variable}}"
                  value={typeof template[field.key] === 'string' && template[field.key]?.includes('{{') ? template[field.key] : ''}
                  onChange={e => updateField(field.key, e.target.value)}
                />
              </div>
            </div>
          ) : field.type === 'textarea' ? (
            <InsertableInput
              label={field.label}
              required={field.required}
              value={template[field.key] || ''}
              onChange={val => updateField(field.key, val)}
              placeholder={`Enter ${field.label.toLowerCase()}...`}
              triggerSource={triggerSource}
              priorSteps={priorSteps}
              multiline
              rows={4}
            />
          ) : field.type === 'variable' ? (
            <InsertableInput
              label={field.label}
              required={field.required}
              value={template[field.key]?.toString() || ''}
              onChange={val => updateField(field.key, val)}
              placeholder={`{{context.company_id}} or numeric ID`}
              triggerSource={triggerSource}
              priorSteps={priorSteps}
            />
          ) : (
            <InsertableInput
              label={field.label}
              required={field.required}
              value={template[field.key]?.toString() || ''}
              onChange={val => updateField(field.key, val)}
              placeholder={`Enter ${field.label.toLowerCase()}...`}
              triggerSource={triggerSource}
              priorSteps={priorSteps}
            />
          )}
        </div>
      ))}
    </div>
  );
}

function UpdateTicketEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  const fields: Record<string, any> = config.fields || {};

  return (
    <div className="space-y-3">
      <InsertableInput
        label="Ticket ID"
        required
        value={config.ticket_id || ''}
        onChange={val => onChange({ ...config, ticket_id: val })}
        placeholder="{{context.ticket_id}}"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      <div className="text-xs font-semibold text-muted-foreground">Fields to Update</div>
      {TICKET_FIELDS.filter(f => f.key !== 'title' && f.key !== 'description').map(field => (
        <InsertableInput
          key={field.key}
          label={field.label}
          value={fields[field.key]?.toString() || ''}
          onChange={val => onChange({ ...config, fields: { ...fields, [field.key]: val || undefined } })}
          placeholder={`Leave blank to skip`}
          triggerSource={triggerSource}
          priorSteps={priorSteps}
        />
      ))}
    </div>
  );
}

function CreateNoteEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  return (
    <div className="space-y-3">
      <InsertableInput
        label="Ticket ID"
        required
        value={config.ticket_id || ''}
        onChange={val => onChange({ ...config, ticket_id: val })}
        placeholder="{{context.ticket_id}}"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      <InsertableInput
        label="Note Title"
        value={config.title || ''}
        onChange={val => onChange({ ...config, title: val })}
        placeholder="Pipeline Note"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      <InsertableInput
        label="Note Body"
        value={config.body || ''}
        onChange={val => onChange({ ...config, body: val })}
        placeholder="Note content..."
        triggerSource={triggerSource}
        priorSteps={priorSteps}
        multiline
        rows={5}
      />
      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="text-xs font-medium text-muted-foreground">Note Type</label>
          <select
            className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
            value={config.note_type || '1'}
            onChange={e => onChange({ ...config, note_type: Number(e.target.value) })}
          >
            <option value="1">Internal</option>
            <option value="2">External</option>
          </select>
        </div>
        <div>
          <label className="text-xs font-medium text-muted-foreground">Publish</label>
          <select
            className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
            value={config.publish || '1'}
            onChange={e => onChange({ ...config, publish: Number(e.target.value) })}
          >
            <option value="1">Yes</option>
            <option value="0">No</option>
          </select>
        </div>
      </div>
    </div>
  );
}

function EnrichEditor({ config, onChange, triggerSource, priorSteps, stepType }: StepConfigEditorProps & { stepType: string }) {
  const lookupOptions: Record<string, { key: string; label: string }[]> = {
    enrich_device: [{ key: 'device_uid', label: 'Device UID' }],
    enrich_company: [
      { key: 'site_name', label: 'Site Name' },
      { key: 'site_uid', label: 'Site UID' },
    ],
    enrich_ticket: [
      { key: 'ticket_number', label: 'Ticket Number' },
      { key: 'ticket_id', label: 'Ticket ID' },
    ],
  };

  const options = lookupOptions[stepType] || [];
  const outputs = STEP_OUTPUT_FIELDS[stepType] || [];

  return (
    <div className="space-y-3">
      <div>
        <label className="text-xs font-medium text-muted-foreground">Lookup By</label>
        <select
          className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
          value={config.lookup_by || options[0]?.key || ''}
          onChange={e => onChange({ ...config, lookup_by: e.target.value })}
        >
          {options.map(o => <option key={o.key} value={o.key}>{o.label}</option>)}
        </select>
      </div>
      <InsertableInput
        label="Source Value"
        required
        value={config.source_field || ''}
        onChange={val => onChange({ ...config, source_field: val })}
        placeholder={`{{trigger.${config.lookup_by || options[0]?.key || 'field'}}}`}
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      {outputs.length > 0 && (
        <div>
          <div className="text-xs font-semibold text-muted-foreground mb-1">Output Fields (added to context)</div>
          <div className="flex flex-wrap gap-1">
            {outputs.map(f => (
              <Badge key={f.key} variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">
                {f.label} → context.{f.key}
              </Badge>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

function NotifyEditor({ config, onChange, channels, triggerSource, priorSteps }: StepConfigEditorProps) {
  return (
    <div className="space-y-3">
      <div>
        <label className="text-xs font-medium text-muted-foreground">Channel <span className="text-red-400">*</span></label>
        <select
          className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
          value={config.channel_id || ''}
          onChange={e => onChange({ ...config, channel_id: Number(e.target.value) })}
        >
          <option value="">Select channel...</option>
          {channels.map(ch => (
            <option key={ch.id} value={ch.id}>{ch.name} ({ch.channel_type})</option>
          ))}
        </select>
        {channels.length === 0 && (
          <p className="text-xs text-muted-foreground mt-1">
            No channels configured. <a href="/admin/workflow/channels" className="text-blue-500 underline">Add one</a>
          </p>
        )}
      </div>
      <InsertableInput
        label="Title"
        value={config.title || ''}
        onChange={val => onChange({ ...config, title: val })}
        placeholder="Notification title"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      <InsertableInput
        label="Message"
        required
        value={config.message || ''}
        onChange={val => onChange({ ...config, message: val })}
        placeholder="Notification message..."
        triggerSource={triggerSource}
        priorSteps={priorSteps}
        multiline
        rows={4}
      />
    </div>
  );
}

function ApprovalEditor({ config, onChange, channels, triggerSource, priorSteps }: StepConfigEditorProps) {
  const options: string[] = config.options || ['Approve', 'Reject'];

  return (
    <div className="space-y-3">
      <div>
        <label className="text-xs font-medium text-muted-foreground">Channel</label>
        <select
          className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
          value={config.channel_id || ''}
          onChange={e => onChange({ ...config, channel_id: Number(e.target.value) })}
        >
          <option value="">Select channel...</option>
          {channels.map(ch => (
            <option key={ch.id} value={ch.id}>{ch.name} ({ch.channel_type})</option>
          ))}
        </select>
      </div>
      <InsertableInput
        label="Message"
        required
        value={config.message || ''}
        onChange={val => onChange({ ...config, message: val })}
        placeholder="Approval request message..."
        triggerSource={triggerSource}
        priorSteps={priorSteps}
        multiline
        rows={3}
      />
      <div>
        <label className="text-xs font-medium text-muted-foreground">Options</label>
        <div className="flex flex-wrap gap-2 mt-1">
          {options.map((opt, i) => (
            <div key={i} className="flex items-center gap-1 bg-muted rounded px-2 py-1">
              <input
                className="px-1.5 py-0.5 text-xs border rounded bg-background w-24"
                value={opt}
                onChange={e => {
                  const updated = [...options];
                  updated[i] = e.target.value;
                  onChange({ ...config, options: updated });
                }}
              />
              <Button variant="ghost" size="icon" className="h-5 w-5" onClick={() => {
                onChange({ ...config, options: options.filter((_, j) => j !== i) });
              }}>
                <Trash2 className="h-2.5 w-2.5 text-red-400" />
              </Button>
            </div>
          ))}
          <Button variant="outline" size="sm" className="h-7 text-xs" onClick={() => {
            onChange({ ...config, options: [...options, 'Option'] });
          }}>
            <Plus className="h-2.5 w-2.5 mr-1" /> Add
          </Button>
        </div>
      </div>
      <div>
        <label className="text-xs font-medium text-muted-foreground">Timeout (minutes)</label>
        <input
          className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
          type="number"
          value={config.timeout_min || 60}
          onChange={e => onChange({ ...config, timeout_min: Number(e.target.value) })}
        />
      </div>
    </div>
  );
}

function AiAnalyzeEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  return (
    <div className="space-y-3">
      <InsertableInput
        label="System Prompt"
        value={config.system_prompt || ''}
        onChange={val => onChange({ ...config, system_prompt: val })}
        placeholder="You are a helpful IT operations assistant."
        triggerSource={triggerSource}
        priorSteps={priorSteps}
        multiline
        rows={2}
      />
      <InsertableInput
        label="Prompt"
        required
        value={config.prompt || ''}
        onChange={val => onChange({ ...config, prompt: val })}
        placeholder="Summarize this alert..."
        triggerSource={triggerSource}
        priorSteps={priorSteps}
        multiline
        rows={5}
      />
      <div className="grid grid-cols-3 gap-3">
        <div>
          <label className="text-xs font-medium text-muted-foreground">Provider</label>
          <select
            className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
            value={config.provider || ''}
            onChange={e => onChange({ ...config, provider: e.target.value || undefined })}
          >
            <option value="">Default</option>
            <option value="openai">OpenAI</option>
            <option value="anthropic">Anthropic</option>
          </select>
        </div>
        <div>
          <label className="text-xs font-medium text-muted-foreground">Model</label>
          <input
            className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
            placeholder="Default from settings"
            value={config.model || ''}
            onChange={e => onChange({ ...config, model: e.target.value || undefined })}
          />
        </div>
        <div>
          <label className="text-xs font-medium text-muted-foreground">Max Tokens</label>
          <input
            className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
            type="number"
            placeholder="2000"
            value={config.max_tokens || ''}
            onChange={e => onChange({ ...config, max_tokens: Number(e.target.value) || undefined })}
          />
        </div>
      </div>
      <div>
        <div className="text-xs font-semibold text-muted-foreground mb-1">Output Fields</div>
        <div className="flex flex-wrap gap-1">
          <Badge variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">ai_response</Badge>
          <Badge variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">ai_provider</Badge>
          <Badge variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">ai_model</Badge>
        </div>
      </div>
    </div>
  );
}

function RmmQuickJobEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  return (
    <div className="space-y-3">
      <InsertableInput
        label="Device UID"
        required
        value={config.device_uid || ''}
        onChange={val => onChange({ ...config, device_uid: val })}
        placeholder="{{context.device_uid}}"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      <InsertableInput
        label="Component UID"
        required
        value={config.component_uid || ''}
        onChange={val => onChange({ ...config, component_uid: val })}
        placeholder="comp-xxx-yyy"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      <InsertableInput
        label="Job Name"
        value={config.job_name || ''}
        onChange={val => onChange({ ...config, job_name: val })}
        placeholder="Quick Job Name"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      <p className="text-xs text-muted-foreground">
        Use <code className="bg-muted px-1 rounded">GET /api/rmm/components</code> to find available component UIDs.
      </p>
    </div>
  );
}

function SetVariableEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  return (
    <div className="space-y-3">
      <div>
        <label className="text-xs font-medium text-muted-foreground">Variable Name <span className="text-red-400">*</span></label>
        <input
          className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
          placeholder="my_variable"
          value={config.key || ''}
          onChange={e => onChange({ ...config, key: e.target.value })}
        />
      </div>
      <InsertableInput
        label="Value"
        required
        value={config.value || ''}
        onChange={val => onChange({ ...config, value: val })}
        placeholder="Static value or {{variable}}"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
    </div>
  );
}

function DelayEditor({ config, onChange }: StepConfigEditorProps) {
  return (
    <div>
      <label className="text-xs font-medium text-muted-foreground">Delay (seconds)</label>
      <input
        className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
        type="number"
        min={0}
        value={config.seconds || 0}
        onChange={e => onChange({ ...config, seconds: Number(e.target.value) })}
      />
    </div>
  );
}

function RmmGetJobResultsEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  return (
    <div className="space-y-3">
      <InsertableInput
        label="Job UID"
        required
        value={config.job_uid || ''}
        onChange={val => onChange({ ...config, job_uid: val })}
        placeholder="{{context.job_uid}}"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      <InsertableInput
        label="Device UID"
        required
        value={config.device_uid || ''}
        onChange={val => onChange({ ...config, device_uid: val })}
        placeholder="{{context.device_uid}}"
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
    </div>
  );
}

// ============================================================================
// Helper
// ============================================================================

function getContextFields(priorSteps: { step_type: string; name: string; config: Record<string, any> }[]) {
  const fields: { key: string; label: string }[] = [];
  for (const step of priorSteps) {
    const outputs = STEP_OUTPUT_FIELDS[step.step_type] || [];
    fields.push(...outputs);
    if (step.step_type === 'transform' && step.config.mappings) {
      for (const key of Object.keys(step.config.mappings)) {
        fields.push({ key, label: key });
      }
    }
    if (step.step_type === 'set_variable' && step.config.key) {
      fields.push({ key: step.config.key, label: step.config.key });
    }
    if (step.step_type === 'db_query' && step.config.output_key) {
      fields.push({ key: step.config.output_key, label: `${step.config.output_key} (query)` });
      fields.push({ key: `${step.config.output_key}_count`, label: `${step.config.output_key}_count` });
    }
    if (step.step_type === 'fetch_b2_result' && step.config.output_key) {
      fields.push({ key: step.config.output_key, label: `${step.config.output_key} (B2 JSON)` });
      fields.push({ key: `${step.config.output_key}_raw_length`, label: `${step.config.output_key}_raw_length` });
      fields.push({ key: 'b2_object_key', label: 'b2_object_key' });
    }
  }
  return fields;
}

function EnrichVspcEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  const outputs = STEP_OUTPUT_FIELDS['enrich_vspc'] || [];

  return (
    <div className="space-y-3">
      <div>
        <label className="text-xs font-medium text-muted-foreground">Lookup By</label>
        <select
          className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
          value={config.lookup_by || 'device_name'}
          onChange={e => onChange({ ...config, lookup_by: e.target.value })}
        >
          <option value="device_name">Device Name (hostname)</option>
          <option value="organization_uid">Organization UID</option>
        </select>
      </div>
      <InsertableInput
        label="Source Value"
        required
        value={config.source_field || ''}
        onChange={val => onChange({ ...config, source_field: val })}
        placeholder={config.lookup_by === 'organization_uid' ? '{{context.org_uid}}' : '{{trigger.device_hostname}}'}
        triggerSource={triggerSource}
        priorSteps={priorSteps}
      />
      <div className="bg-blue-50 border border-blue-200 rounded p-3 space-y-2">
        <div className="text-xs font-semibold text-blue-700">What this step does</div>
        <ul className="text-xs text-blue-600 space-y-0.5 list-disc pl-4">
          <li>Queries local Veeam VSPC data for backup agent jobs matching the device</li>
          <li>Checks backup server jobs and protected workloads (VM-level)</li>
          <li>Retrieves active VSPC alarms for the device</li>
          <li>Calculates hours since last successful backup</li>
          <li>Builds a text summary of all findings</li>
        </ul>
      </div>
      {outputs.length > 0 && (
        <div>
          <div className="text-xs font-semibold text-muted-foreground mb-1">Output Fields (added to context)</div>
          <div className="flex flex-wrap gap-1">
            {outputs.map(f => (
              <Badge key={f.key} variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">
                {f.label} → context.{f.key}
              </Badge>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

function DbQueryEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  const outputKey = config.output_key || 'query_result';

  return (
    <div className="space-y-3">
      <div>
        <div className="flex items-center justify-between">
          <label className="text-xs font-medium text-muted-foreground">SQL Query <span className="text-red-400">*</span></label>
          <span className="text-[10px] text-muted-foreground">Read-only SELECT only. Use $1, $2 for params.</span>
        </div>
        <textarea
          className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background font-mono"
          rows={6}
          placeholder={`SELECT status, failure_message, last_run\nFROM veeam_backup_agent_jobs\nWHERE LOWER(name) LIKE LOWER($1)\nORDER BY last_run DESC LIMIT 10`}
          value={config.query || ''}
          onChange={e => onChange({ ...config, query: e.target.value })}
        />
      </div>
      <div>
        <div className="text-xs font-semibold text-muted-foreground mb-1">Query Parameters</div>
        {(config.params || []).map((param: string, i: number) => (
          <div key={i} className="flex items-center gap-2 mb-1">
            <Badge variant="outline" className="font-mono text-xs shrink-0">${i + 1}</Badge>
            <div className="flex-1">
              <InsertableInput
                value={param}
                onChange={val => {
                  const updated = [...(config.params || [])];
                  updated[i] = val;
                  onChange({ ...config, params: updated });
                }}
                placeholder={`Parameter $${i + 1} value`}
                triggerSource={triggerSource}
                priorSteps={priorSteps}
              />
            </div>
            <Button variant="ghost" size="icon" className="h-6 w-6 shrink-0" onClick={() => {
              const updated = (config.params || []).filter((_: any, j: number) => j !== i);
              onChange({ ...config, params: updated });
            }}>
              <Trash2 className="h-3 w-3 text-red-400" />
            </Button>
          </div>
        ))}
        <Button variant="outline" size="sm" className="mt-1" onClick={() => {
          onChange({ ...config, params: [...(config.params || []), ''] });
        }}>
          <Plus className="h-3 w-3 mr-1" /> Add Parameter
        </Button>
      </div>
      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="text-xs font-medium text-muted-foreground">Output Key</label>
          <input
            className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
            placeholder="query_result"
            value={config.output_key || ''}
            onChange={e => onChange({ ...config, output_key: e.target.value || undefined })}
          />
          <p className="text-[10px] text-muted-foreground mt-0.5">Results stored as context.{outputKey}</p>
        </div>
        <div>
          <label className="text-xs font-medium text-muted-foreground">Result Mode</label>
          <select
            className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
            value={config.single_row ? 'single' : 'array'}
            onChange={e => onChange({ ...config, single_row: e.target.value === 'single' })}
          >
            <option value="array">All rows (array)</option>
            <option value="single">First row only (object)</option>
          </select>
        </div>
      </div>
      <div className="bg-amber-50 border border-amber-200 rounded p-2">
        <div className="text-xs text-amber-700">
          <strong>Security:</strong> Only SELECT queries allowed. INSERT, UPDATE, DELETE, DROP, etc. are blocked.
        </div>
      </div>
      <div>
        <div className="text-xs font-semibold text-muted-foreground mb-1">Output Fields</div>
        <div className="flex flex-wrap gap-1">
          <Badge variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">
            {outputKey} → query rows
          </Badge>
          <Badge variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">
            {outputKey}_count → row count
          </Badge>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// Fetch B2 Result Editor
// ============================================================================

function FetchB2ResultEditor({ config, onChange, triggerSource, priorSteps }: StepConfigEditorProps) {
  const outputKey = config.output_key || 'b2_result';
  return (
    <div className="space-y-3">
      <div>
        <label className="text-xs font-medium text-muted-foreground">Object Key</label>
        <InsertableInput
          value={config.object_key || ''}
          onChange={v => onChange({ ...config, object_key: v })}
          placeholder="diagnostics/{{context.device_hostname}}/result.json"
          triggerSource={triggerSource}
          priorSteps={priorSteps}
        />
        <p className="text-[10px] text-muted-foreground mt-0.5">S3 object key in the B2 bucket. Use template variables from prior steps.</p>
      </div>
      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="text-xs font-medium text-muted-foreground">Output Key</label>
          <input
            className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
            placeholder="diagnostic_results"
            value={config.output_key || ''}
            onChange={e => onChange({ ...config, output_key: e.target.value || undefined })}
          />
          <p className="text-[10px] text-muted-foreground mt-0.5">Parsed JSON stored as context.{outputKey}</p>
        </div>
        <div>
          <label className="text-xs font-medium text-muted-foreground">Bucket</label>
          <input
            className="w-full mt-1 px-2.5 py-1.5 text-sm border rounded bg-background"
            placeholder="wulf-audits (default)"
            value={config.bucket || ''}
            onChange={e => onChange({ ...config, bucket: e.target.value || undefined })}
          />
          <p className="text-[10px] text-muted-foreground mt-0.5">Leave blank for default B2_BUCKET</p>
        </div>
      </div>
      <div className="bg-blue-50 border border-blue-200 rounded p-2">
        <div className="text-xs text-blue-700">
          <strong>How it works:</strong> Generates a presigned S3 URL, downloads the file, and parses JSON into the pipeline context.
        </div>
      </div>
      <div>
        <div className="text-xs font-semibold text-muted-foreground mb-1">Output Fields</div>
        <div className="flex flex-wrap gap-1">
          <Badge variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">
            {outputKey} → parsed JSON
          </Badge>
          <Badge variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">
            {outputKey}_raw_length → byte count
          </Badge>
          <Badge variant="outline" className="text-[10px] bg-green-50 text-green-600 border-green-200">
            b2_object_key → key used
          </Badge>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// Main Export — routes to the correct editor
// ============================================================================

export default function StepConfigEditor(props: StepConfigEditorProps) {
  const { stepType } = props;

  switch (stepType) {
    case 'transform':
      return <TransformEditor {...props} />;
    case 'filter':
      return <FilterEditor {...props} />;
    case 'create_ticket':
      return <CreateTicketEditor {...props} />;
    case 'update_ticket':
      return <UpdateTicketEditor {...props} />;
    case 'create_note':
      return <CreateNoteEditor {...props} />;
    case 'enrich_device':
    case 'enrich_company':
    case 'enrich_ticket':
      return <EnrichEditor {...props} stepType={stepType} />;
    case 'notify':
      return <NotifyEditor {...props} />;
    case 'approval':
      return <ApprovalEditor {...props} />;
    case 'ai_analyze':
      return <AiAnalyzeEditor {...props} />;
    case 'rmm_quick_job':
      return <RmmQuickJobEditor {...props} />;
    case 'rmm_get_job_results':
      return <RmmGetJobResultsEditor {...props} />;
    case 'set_variable':
      return <SetVariableEditor {...props} />;
    case 'delay':
      return <DelayEditor {...props} />;
    case 'enrich_vspc':
      return <EnrichVspcEditor {...props} />;
    case 'db_query':
      return <DbQueryEditor {...props} />;
    case 'fetch_b2_result':
      return <FetchB2ResultEditor {...props} />;
    default:
      // Fallback: raw JSON editor
      return (
        <div>
          <label className="text-xs font-medium text-muted-foreground">Config (JSON)</label>
          <textarea
            className="w-full mt-1 px-2 py-1.5 text-sm border rounded bg-background font-mono"
            rows={6}
            value={JSON.stringify(props.config, null, 2)}
            onChange={e => {
              try { props.onChange(JSON.parse(e.target.value)); } catch {}
            }}
          />
        </div>
      );
  }
}

export { VariablePicker, InsertableInput, TRIGGER_FIELDS, STEP_OUTPUT_FIELDS };
