'use client';

import { useState, useEffect, useCallback } from 'react';
import { useParams, useRouter } from 'next/navigation';
import Link from 'next/link';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Switch } from '@/components/ui/switch';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
  ArrowLeft,
  Plus,
  Save,
  Trash2,
  GripVertical,
  Play,
  ChevronDown,
  ChevronUp,
  AlertCircle,
  CheckCircle2,
  Clock,
  XCircle,
  Loader2,
  Code,
  Eye,
} from 'lucide-react';
import StepConfigEditor from '@/components/admin/pipeline/StepConfigEditor';
import { useUserTimezone } from '@/lib/hooks/use-user-timezone';

interface Pipeline {
  id: number;
  name: string;
  description: string | null;
  is_active: boolean;
  trigger_source: string;
  trigger_conditions: any[];
  sort_order: number;
  steps: PipelineStep[];
  recent_executions: any[];
}

interface PipelineStep {
  id?: number;
  pipeline_id?: number;
  step_order: number;
  step_type: string;
  name: string;
  config: Record<string, any>;
  on_failure: string;
  skip_to_step: number | null;
  is_active: boolean;
  timeout_ms: number | null;
}

const STEP_TYPES = [
  { value: 'filter', label: 'Filter', description: 'Evaluate conditions, skip if not met', category: 'Logic' },
  { value: 'transform', label: 'Transform', description: 'Map payload fields to context', category: 'Logic' },
  { value: 'set_variable', label: 'Set Variable', description: 'Set a context variable', category: 'Logic' },
  { value: 'delay', label: 'Delay', description: 'Wait before next step', category: 'Logic' },
  { value: 'enrich_device', label: 'Enrich Device', description: 'Lookup device from RMM', category: 'Enrich' },
  { value: 'enrich_company', label: 'Enrich Company', description: 'Lookup company from site', category: 'Enrich' },
  { value: 'enrich_ticket', label: 'Enrich Ticket', description: 'Lookup ticket from Autotask', category: 'Enrich' },
  { value: 'enrich_vspc', label: 'Enrich VSPC', description: 'Veeam backup status lookup', category: 'Enrich' },
  { value: 'db_query', label: 'DB Query', description: 'Run SQL query on local DB', category: 'Enrich' },
  { value: 'create_ticket', label: 'Create Ticket', description: 'Create Autotask ticket', category: 'Action' },
  { value: 'update_ticket', label: 'Update Ticket', description: 'Update Autotask ticket', category: 'Action' },
  { value: 'create_note', label: 'Create Note', description: 'Add note to ticket', category: 'Action' },
  { value: 'ai_analyze', label: 'AI Analyze', description: 'Send to AI for analysis', category: 'Action' },
  { value: 'notify', label: 'Notify', description: 'Send notification', category: 'Notify' },
  { value: 'approval', label: 'Approval', description: 'Wait for human approval', category: 'Notify' },
  { value: 'rmm_quick_job', label: 'RMM Quick Job', description: 'Run job on device', category: 'RMM' },
  { value: 'rmm_get_job_results', label: 'RMM Job Results', description: 'Get job results', category: 'RMM' },
  { value: 'fetch_b2_result', label: 'Fetch B2 Result', description: 'Download JSON from B2 storage', category: 'Data' },
];

const CATEGORY_COLORS: Record<string, string> = {
  Logic: 'bg-slate-100 text-slate-700',
  Enrich: 'bg-blue-100 text-blue-700',
  Data: 'bg-cyan-100 text-cyan-700',
  Action: 'bg-green-100 text-green-700',
  Notify: 'bg-orange-100 text-orange-700',
  RMM: 'bg-purple-100 text-purple-700',
};

const STATUS_ICONS: Record<string, any> = {
  completed: <CheckCircle2 className="h-4 w-4 text-green-500" />,
  failed: <XCircle className="h-4 w-4 text-red-500" />,
  running: <Loader2 className="h-4 w-4 text-blue-500 animate-spin" />,
  waiting: <Clock className="h-4 w-4 text-yellow-500" />,
  pending: <Clock className="h-4 w-4 text-gray-400" />,
};

export default function PipelineEditorPage() {
  const tz = useUserTimezone();
  const params = useParams();
  const router = useRouter();
  const pipelineId = params.id as string;

  const [pipeline, setPipeline] = useState<Pipeline | null>(null);
  const [steps, setSteps] = useState<PipelineStep[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [hasChanges, setHasChanges] = useState(false);
  const [expandedStep, setExpandedStep] = useState<number | null>(null);
  const [executions, setExecutions] = useState<any[]>([]);
  const [testPayload, setTestPayload] = useState('{\n  "triggered": "True",\n  "alert_type": "PERF_MON",\n  "alert_priority": "HIGH",\n  "alert_message_en": "Test alert",\n  "device_hostname": "SVR01",\n  "device_uid": "test-uid",\n  "site_name": "Test Site",\n  "site_uid": "test-site-uid"\n}');
  const [testResult, setTestResult] = useState<any>(null);
  const [isTesting, setIsTesting] = useState(false);
  const [channels, setChannels] = useState<{ id: number; name: string; channel_type: string }[]>([]);
  const [jsonMode, setJsonMode] = useState<Record<number, boolean>>({});

  const loadPipeline = useCallback(async () => {
    setIsLoading(true);
    try {
      const res = await fetch(`/api/pipelines/${pipelineId}`);
      if (res.ok) {
        const data = await res.json();
        setPipeline(data);
        setSteps(data.steps || []);
        setExecutions(data.recent_executions || []);
      }
    } catch (err) {
      console.error('Failed to load pipeline:', err);
    } finally {
      setIsLoading(false);
    }
  }, [pipelineId]);

  useEffect(() => { loadPipeline(); loadChannels(); }, [loadPipeline]);

  const loadChannels = async () => {
    try {
      const res = await fetch('/api/notification-channels');
      if (res.ok) {
        const data = await res.json();
        setChannels(data.data || []);
      }
    } catch (err) {
      console.error('Failed to load channels:', err);
    }
  };

  const saveSteps = async () => {
    setIsSaving(true);
    try {
      await fetch(`/api/pipelines/${pipelineId}/steps`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ steps }),
      });
      setHasChanges(false);
      loadPipeline();
    } catch (err) {
      console.error('Failed to save steps:', err);
    } finally {
      setIsSaving(false);
    }
  };

  const savePipelineSettings = async (updates: Partial<Pipeline>) => {
    try {
      const res = await fetch(`/api/pipelines/${pipelineId}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(updates),
      });
      if (res.ok) {
        const data = await res.json();
        setPipeline(prev => prev ? { ...prev, ...data } : prev);
      }
    } catch (err) {
      console.error('Failed to update pipeline:', err);
    }
  };

  const addStep = (stepType: string) => {
    const typeDef = STEP_TYPES.find(t => t.value === stepType);
    const newStep: PipelineStep = {
      step_order: steps.length + 1,
      step_type: stepType,
      name: typeDef?.label || stepType,
      config: {},
      on_failure: 'stop',
      skip_to_step: null,
      is_active: true,
      timeout_ms: null,
    };
    setSteps([...steps, newStep]);
    setExpandedStep(steps.length);
    setHasChanges(true);
  };

  const updateStep = (index: number, updates: Partial<PipelineStep>) => {
    setSteps(prev => prev.map((s, i) => i === index ? { ...s, ...updates } : s));
    setHasChanges(true);
  };

  const removeStep = (index: number) => {
    setSteps(prev => {
      const updated = prev.filter((_, i) => i !== index);
      return updated.map((s, i) => ({ ...s, step_order: i + 1 }));
    });
    setHasChanges(true);
  };

  const moveStep = (index: number, direction: 'up' | 'down') => {
    const newIndex = direction === 'up' ? index - 1 : index + 1;
    if (newIndex < 0 || newIndex >= steps.length) return;
    setSteps(prev => {
      const updated = [...prev];
      [updated[index], updated[newIndex]] = [updated[newIndex], updated[index]];
      return updated.map((s, i) => ({ ...s, step_order: i + 1 }));
    });
    setHasChanges(true);
  };

  const runTest = async () => {
    setIsTesting(true);
    setTestResult(null);
    try {
      const payload = JSON.parse(testPayload);
      const res = await fetch(`/api/pipelines/${pipelineId}/test`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ payload }),
      });
      const data = await res.json();
      setTestResult(data);
      loadPipeline();
    } catch (err) {
      setTestResult({ error: err instanceof Error ? err.message : String(err) });
    } finally {
      setIsTesting(false);
    }
  };

  if (isLoading || !pipeline) {
    return <div className="container mx-auto p-6 text-center text-muted-foreground">Loading...</div>;
  }

  return (
    <div className="container mx-auto p-6 space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <Link href="/admin/workflow/pipelines">
            <Button variant="ghost" size="icon"><ArrowLeft className="h-4 w-4" /></Button>
          </Link>
          <div>
            <h1 className="text-2xl font-bold">{pipeline.name}</h1>
            <p className="text-muted-foreground text-sm">{pipeline.description || 'No description'}</p>
          </div>
        </div>
        <div className="flex items-center gap-3">
          <div className="flex items-center gap-2">
            <span className="text-sm text-muted-foreground">Active</span>
            <Switch
              checked={pipeline.is_active}
              onCheckedChange={(checked) => savePipelineSettings({ is_active: checked })}
            />
          </div>
          {hasChanges && (
            <Button onClick={saveSteps} disabled={isSaving}>
              <Save className="h-4 w-4 mr-2" />
              {isSaving ? 'Saving...' : 'Save Steps'}
            </Button>
          )}
        </div>
      </div>

      <Tabs defaultValue="steps">
        <TabsList>
          <TabsTrigger value="steps">Steps ({steps.length})</TabsTrigger>
          <TabsTrigger value="trigger">Trigger</TabsTrigger>
          <TabsTrigger value="test">Test</TabsTrigger>
          <TabsTrigger value="history">History ({executions.length})</TabsTrigger>
        </TabsList>

        {/* Steps Tab */}
        <TabsContent value="steps" className="space-y-4">
          {steps.length === 0 ? (
            <Card>
              <CardContent className="py-8 text-center text-muted-foreground">
                No steps yet. Add a step to build your pipeline.
              </CardContent>
            </Card>
          ) : (
            <div className="space-y-2">
              {steps.map((step, index) => {
                const typeDef = STEP_TYPES.find(t => t.value === step.step_type);
                const category = typeDef ? CATEGORY_COLORS[typeDef.category] || '' : '';
                const isExpanded = expandedStep === index;

                return (
                  <Card key={index} className={!step.is_active ? 'opacity-50' : ''}>
                    <CardContent className="py-3">
                      <div className="flex items-center gap-3">
                        <div className="flex flex-col gap-0.5">
                          <Button variant="ghost" size="icon" className="h-5 w-5" onClick={() => moveStep(index, 'up')} disabled={index === 0}>
                            <ChevronUp className="h-3 w-3" />
                          </Button>
                          <Button variant="ghost" size="icon" className="h-5 w-5" onClick={() => moveStep(index, 'down')} disabled={index === steps.length - 1}>
                            <ChevronDown className="h-3 w-3" />
                          </Button>
                        </div>
                        <Badge variant="outline" className="font-mono text-xs w-6 justify-center">{step.step_order}</Badge>
                        <Badge className={category}>{typeDef?.category || 'Other'}</Badge>
                        <div className="flex-1 cursor-pointer" onClick={() => setExpandedStep(isExpanded ? null : index)}>
                          <div className="flex items-center gap-2">
                            <span className="font-medium">{step.name}</span>
                            <span className="text-xs text-muted-foreground">({step.step_type})</span>
                          </div>
                        </div>
                        <Switch
                          checked={step.is_active}
                          onCheckedChange={(checked) => updateStep(index, { is_active: checked })}
                        />
                        <Button variant="ghost" size="icon" onClick={() => removeStep(index)}>
                          <Trash2 className="h-4 w-4 text-red-500" />
                        </Button>
                      </div>

                      {isExpanded && (
                        <div className="mt-4 pl-12 space-y-3 border-t pt-3">
                          <div className="grid grid-cols-2 gap-3">
                            <div>
                              <label className="text-xs font-medium text-muted-foreground">Step Name</label>
                              <input
                                className="w-full mt-1 px-2 py-1.5 text-sm border rounded bg-background"
                                value={step.name}
                                onChange={e => updateStep(index, { name: e.target.value })}
                              />
                            </div>
                            <div>
                              <label className="text-xs font-medium text-muted-foreground">On Failure</label>
                              <select
                                className="w-full mt-1 px-2 py-1.5 text-sm border rounded bg-background"
                                value={step.on_failure}
                                onChange={e => updateStep(index, { on_failure: e.target.value })}
                              >
                                <option value="stop">Stop Pipeline</option>
                                <option value="continue">Continue</option>
                                <option value="skip_to">Skip To Step</option>
                              </select>
                            </div>
                          </div>

                          {/* Visual / JSON toggle */}
                          <div className="flex items-center justify-end gap-1">
                            <Button
                              variant={jsonMode[index] ? 'ghost' : 'secondary'}
                              size="sm"
                              className="h-6 text-xs px-2"
                              onClick={() => setJsonMode(prev => ({ ...prev, [index]: false }))}
                            >
                              <Eye className="h-3 w-3 mr-1" /> Visual
                            </Button>
                            <Button
                              variant={jsonMode[index] ? 'secondary' : 'ghost'}
                              size="sm"
                              className="h-6 text-xs px-2"
                              onClick={() => setJsonMode(prev => ({ ...prev, [index]: true }))}
                            >
                              <Code className="h-3 w-3 mr-1" /> JSON
                            </Button>
                          </div>

                          {jsonMode[index] ? (
                            <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={8}
                                value={JSON.stringify(step.config, null, 2)}
                                onChange={e => {
                                  try {
                                    const parsed = JSON.parse(e.target.value);
                                    updateStep(index, { config: parsed });
                                  } catch {
                                    // Allow invalid JSON while typing
                                  }
                                }}
                              />
                            </div>
                          ) : (
                            <StepConfigEditor
                              stepType={step.step_type}
                              config={step.config}
                              triggerSource={pipeline.trigger_source}
                              priorSteps={steps.slice(0, index).map(s => ({
                                step_type: s.step_type,
                                name: s.name,
                                config: s.config,
                              }))}
                              channels={channels}
                              onChange={config => updateStep(index, { config })}
                            />
                          )}
                        </div>
                      )}
                    </CardContent>
                  </Card>
                );
              })}
            </div>
          )}

          {/* Add Step */}
          <Card>
            <CardHeader>
              <CardTitle className="text-sm">Add Step</CardTitle>
            </CardHeader>
            <CardContent>
              <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-2">
                {STEP_TYPES.map(type => (
                  <Button
                    key={type.value}
                    variant="outline"
                    className="h-auto py-2 px-3 flex flex-col items-start text-left"
                    onClick={() => addStep(type.value)}
                  >
                    <div className="flex items-center gap-1.5">
                      <Badge className={`${CATEGORY_COLORS[type.category]} text-[10px] px-1`}>{type.category}</Badge>
                      <span className="text-xs font-medium">{type.label}</span>
                    </div>
                    <span className="text-[10px] text-muted-foreground mt-0.5">{type.description}</span>
                  </Button>
                ))}
              </div>
            </CardContent>
          </Card>
        </TabsContent>

        {/* Trigger Tab */}
        <TabsContent value="trigger" className="space-y-4">
          <Card>
            <CardHeader>
              <CardTitle className="text-lg">Trigger Configuration</CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="text-sm font-medium">Pipeline Name</label>
                  <input
                    className="w-full mt-1 px-3 py-2 border rounded-md bg-background"
                    value={pipeline.name}
                    onChange={e => savePipelineSettings({ name: e.target.value })}
                  />
                </div>
                <div>
                  <label className="text-sm font-medium">Trigger Source</label>
                  <select
                    className="w-full mt-1 px-3 py-2 border rounded-md bg-background"
                    value={pipeline.trigger_source}
                    onChange={e => savePipelineSettings({ trigger_source: e.target.value } as any)}
                  >
                    <option value="datto_rmm">Datto RMM</option>
                    <option value="autotask">Autotask</option>
                    <option value="veeam">Veeam</option>
                    <option value="manual">Manual</option>
                  </select>
                </div>
              </div>
              <div>
                <label className="text-sm font-medium">Description</label>
                <textarea
                  className="w-full mt-1 px-3 py-2 border rounded-md bg-background"
                  rows={2}
                  value={pipeline.description || ''}
                  onChange={e => savePipelineSettings({ description: e.target.value })}
                />
              </div>
              <div>
                <label className="text-sm font-medium">Trigger Conditions (JSON)</label>
                <p className="text-xs text-muted-foreground mb-1">
                  Array of conditions: {`[{"field": "triggered", "operator": "equals", "value": "True"}]`}
                </p>
                <textarea
                  className="w-full mt-1 px-3 py-2 border rounded-md bg-background font-mono text-sm"
                  rows={5}
                  defaultValue={JSON.stringify(pipeline.trigger_conditions, null, 2)}
                  onBlur={e => {
                    try {
                      const parsed = JSON.parse(e.target.value);
                      savePipelineSettings({ trigger_conditions: parsed });
                    } catch {}
                  }}
                />
              </div>
            </CardContent>
          </Card>
        </TabsContent>

        {/* Test Tab */}
        <TabsContent value="test" className="space-y-4">
          <Card>
            <CardHeader>
              <CardTitle className="text-lg">Test Pipeline</CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              <div>
                <label className="text-sm font-medium">Sample Payload (JSON)</label>
                <textarea
                  className="w-full mt-1 px-3 py-2 border rounded-md bg-background font-mono text-sm"
                  rows={12}
                  value={testPayload}
                  onChange={e => setTestPayload(e.target.value)}
                />
              </div>
              <Button onClick={runTest} disabled={isTesting}>
                <Play className="h-4 w-4 mr-2" />
                {isTesting ? 'Running...' : 'Run Test'}
              </Button>

              {testResult && (
                <div className="mt-4 space-y-3">
                  {testResult.error ? (
                    <div className="p-3 bg-red-50 border border-red-200 rounded text-red-700 text-sm">
                      <AlertCircle className="h-4 w-4 inline mr-2" />
                      {testResult.error}
                    </div>
                  ) : (
                    <>
                      <div className={`p-3 rounded text-sm ${testResult.matched ? 'bg-green-50 border border-green-200 text-green-700' : 'bg-yellow-50 border border-yellow-200 text-yellow-700'}`}>
                        {testResult.matched ? '✓ Trigger conditions matched' : '✗ Trigger conditions did not match'}
                      </div>
                      {testResult.execution && (
                        <div className="p-3 bg-muted rounded text-sm space-y-2">
                          <div className="flex items-center gap-2">
                            {STATUS_ICONS[testResult.execution.status]}
                            <span className="font-medium">Execution #{testResult.execution.id}: {testResult.execution.status}</span>
                            {testResult.execution.duration_ms && (
                              <span className="text-muted-foreground">({testResult.execution.duration_ms}ms)</span>
                            )}
                          </div>
                          {testResult.execution.error_message && (
                            <div className="text-red-600 text-xs">{testResult.execution.error_message}</div>
                          )}
                        </div>
                      )}
                      {testResult.steps && testResult.steps.length > 0 && (
                        <div className="space-y-1">
                          {testResult.steps.map((s: any, i: number) => (
                            <div key={i} className="flex items-center gap-2 text-sm p-2 bg-muted/50 rounded">
                              {STATUS_ICONS[s.status] || STATUS_ICONS.pending}
                              <Badge variant="outline" className="text-xs">{s.step_order}</Badge>
                              <span>{s.step_name || s.step_type}</span>
                              <span className="text-muted-foreground text-xs">({s.step_type})</span>
                              {s.duration_ms != null && <span className="text-xs text-muted-foreground ml-auto">{s.duration_ms}ms</span>}
                              {s.error_message && <span className="text-xs text-red-500 ml-2">{s.error_message}</span>}
                            </div>
                          ))}
                        </div>
                      )}
                    </>
                  )}
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        {/* History Tab */}
        <TabsContent value="history" className="space-y-4">
          {executions.length === 0 ? (
            <Card>
              <CardContent className="py-8 text-center text-muted-foreground">
                No executions yet.
              </CardContent>
            </Card>
          ) : (
            <div className="space-y-2">
              {executions.map((exec: any) => (
                <Card key={exec.id}>
                  <CardContent className="py-3">
                    <div className="flex items-center gap-3">
                      {STATUS_ICONS[exec.status] || STATUS_ICONS.pending}
                      <span className="font-medium">#{exec.id}</span>
                      <Badge variant="outline">{exec.status}</Badge>
                      <span className="text-sm text-muted-foreground">{exec.trigger_source}</span>
                      {exec.duration_ms && <span className="text-sm text-muted-foreground">{exec.duration_ms}ms</span>}
                      <span className="text-xs text-muted-foreground ml-auto">
                        {new Date(exec.started_at).toLocaleString(undefined, { timeZone: tz })}
                      </span>
                    </div>
                    {exec.error_message && (
                      <p className="text-xs text-red-500 mt-1 pl-7">{exec.error_message}</p>
                    )}
                  </CardContent>
                </Card>
              ))}
            </div>
          )}
        </TabsContent>
      </Tabs>
    </div>
  );
}
