import { useState, useCallback, useEffect, useMemo } from "react";
import { useParams, useNavigate } from "react-router";
import {
  ReactFlow,
  Edge,
  Controls,
  Background,
  Handle,
  Position,
  BackgroundVariant,
  MarkerType,
} from "@xyflow/react";
import "@xyflow/react/dist/style.css";
import { Masthead } from "../components/Masthead";
import { useDirectives, useDirectiveEventSubscription } from "../hooks/useDirectives";
import { useAuth } from "../contexts/AuthContext";
import type {
  DirectiveSummary,
  DirectiveWithProgress,
  DirectiveGraphResponse,
  DirectiveGraphNode,
  CreateDirectiveRequest,
  RepositoryHistoryEntry,
  AutonomyLevel,
  StepStatus,
  ConfidenceLevel,
} from "../lib/api";
import { getRepositorySuggestions } from "../lib/api";

export default function DirectivesPage() {
  const { isAuthenticated, isAuthConfigured, isLoading: authLoading } = useAuth();
  const navigate = useNavigate();

  // Redirect to login if not authenticated (when auth is configured)
  useEffect(() => {
    if (!authLoading && isAuthConfigured && !isAuthenticated) {
      navigate("/login");
    }
  }, [authLoading, isAuthConfigured, isAuthenticated, navigate]);

  // Show loading while checking auth
  if (authLoading) {
    return (
      <div className="relative z-10 min-h-screen flex flex-col bg-[#0a1628]">
        <Masthead showNav />
        <main className="flex-1 flex items-center justify-center">
          <p className="text-[#7788aa] font-mono text-sm">Loading...</p>
        </main>
      </div>
    );
  }

  // Don't render if not authenticated (will redirect)
  if (isAuthConfigured && !isAuthenticated) {
    return null;
  }

  return <DirectivesPageContent />;
}

function DirectivesPageContent() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const {
    directives,
    loading,
    error,
    createNewDirective,
    archiveExistingDirective,
    getDirectiveById,
    getGraph,
    start,
    pause,
    resume,
    stop,
  } = useDirectives();

  const [directiveDetail, setDirectiveDetail] = useState<DirectiveWithProgress | null>(null);
  const [directiveGraph, setDirectiveGraph] = useState<DirectiveGraphResponse | null>(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [isCreating, setIsCreating] = useState(false);

  // Load directive detail when ID changes
  useEffect(() => {
    if (id) {
      setDetailLoading(true);
      Promise.all([getDirectiveById(id), getGraph(id).catch(() => null)]).then(([directive, graph]) => {
        setDirectiveDetail(directive);
        setDirectiveGraph(graph);
        setDetailLoading(false);
      });
    } else {
      setDirectiveDetail(null);
      setDirectiveGraph(null);
    }
  }, [id, getDirectiveById, getGraph]);

  const handleSelect = useCallback(
    (directiveId: string) => {
      navigate(`/directives/${directiveId}`);
    },
    [navigate]
  );

  const handleBack = useCallback(() => {
    navigate("/directives");
  }, [navigate]);

  const handleCreate = useCallback(() => {
    setIsCreating(true);
  }, []);

  const handleCreateSubmit = useCallback(
    async (goal: string, repositoryUrl: string | undefined, autonomyLevel: AutonomyLevel) => {
      const data: CreateDirectiveRequest = {
        goal: goal.trim(),
        repositoryUrl: repositoryUrl?.trim() || undefined,
        autonomyLevel,
      };

      try {
        const result = await createNewDirective(data);
        if (result) {
          setIsCreating(false);
          navigate(`/directives/${result.id}`);
        }
      } catch (err) {
        console.error("Failed to create directive:", err);
      }
    },
    [createNewDirective, navigate]
  );

  const handleCreateCancel = useCallback(() => {
    setIsCreating(false);
  }, []);

  const handleArchive = useCallback(
    async (directive: DirectiveSummary) => {
      if (confirm(`Are you sure you want to archive this directive?`)) {
        const success = await archiveExistingDirective(directive.id);
        if (success && directive.id === id) {
          navigate("/directives");
        }
      }
    },
    [archiveExistingDirective, id, navigate]
  );

  const handleRefresh = useCallback(async () => {
    if (id) {
      const [directive, graph] = await Promise.all([
        getDirectiveById(id),
        getGraph(id).catch(() => null),
      ]);
      setDirectiveDetail(directive);
      setDirectiveGraph(graph);
    }
  }, [id, getDirectiveById, getGraph]);

  const handleStart = useCallback(async () => {
    if (id) {
      await start(id);
      handleRefresh();
    }
  }, [id, start, handleRefresh]);

  const handlePause = useCallback(async () => {
    if (id) {
      await pause(id);
      handleRefresh();
    }
  }, [id, pause, handleRefresh]);

  const handleResume = useCallback(async () => {
    if (id) {
      await resume(id);
      handleRefresh();
    }
  }, [id, resume, handleRefresh]);

  const handleStop = useCallback(async () => {
    if (id) {
      await stop(id);
      handleRefresh();
    }
  }, [id, stop, handleRefresh]);

  return (
    <div className="relative z-10 min-h-screen flex flex-col bg-[#0a1628]">
      <Masthead showNav />
      <main className="flex-1 flex flex-col p-4 pt-2 gap-4 overflow-hidden">
        {error && (
          <div className="p-3 bg-red-400/10 border border-red-400/30 text-red-400 font-mono text-sm">
            {error}
          </div>
        )}

        {/* Create directive modal */}
        {isCreating && (
          <CreateDirectiveModal
            onSubmit={handleCreateSubmit}
            onCancel={handleCreateCancel}
          />
        )}

        <div className="flex-1 grid grid-cols-[350px_1fr] gap-4 min-h-0">
          {/* Directive list */}
          <DirectiveList
            directives={directives}
            loading={loading}
            onSelect={handleSelect}
            onCreate={handleCreate}
            selectedId={id}
            onArchive={handleArchive}
          />

          {/* Directive detail or empty state */}
          {directiveDetail ? (
            <DirectiveDetail
              directive={directiveDetail}
              graph={directiveGraph}
              loading={detailLoading}
              onBack={handleBack}
              onRefresh={handleRefresh}
              onStart={handleStart}
              onPause={handlePause}
              onResume={handleResume}
              onStop={handleStop}
            />
          ) : (
            <div className="panel h-full flex items-center justify-center">
              <div className="text-center">
                <p className="font-mono text-sm text-[#555] mb-4">
                  Select a directive or create a new one
                </p>
                <button
                  onClick={handleCreate}
                  className="px-4 py-2 font-mono text-xs text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3] hover:bg-[#153667] transition-colors uppercase"
                >
                  + New Directive
                </button>
              </div>
            </div>
          )}
        </div>
      </main>
    </div>
  );
}

// =============================================================================
// Directive List Component
// =============================================================================

interface DirectiveListProps {
  directives: DirectiveSummary[];
  loading: boolean;
  onSelect: (id: string) => void;
  onCreate: () => void;
  selectedId?: string;
  onArchive: (directive: DirectiveSummary) => void;
}

function DirectiveList({
  directives,
  loading,
  onSelect,
  onCreate,
  selectedId,
  onArchive,
}: DirectiveListProps) {
  const [filter, setFilter] = useState<"all" | "active" | "completed" | "failed">("all");

  const filteredDirectives = directives.filter((d) => {
    if (filter === "all") return true;
    if (filter === "active") return ["draft", "planning", "active", "paused"].includes(d.status);
    if (filter === "completed") return d.status === "completed";
    if (filter === "failed") return d.status === "failed";
    return true;
  });

  return (
    <div className="panel h-full flex flex-col overflow-hidden">
      <div className="flex items-center justify-between p-3 border-b border-[rgba(117,170,252,0.15)]">
        <h2 className="font-mono text-sm text-[#75aafc] uppercase">Directives</h2>
        <button
          onClick={onCreate}
          className="px-3 py-1 font-mono text-[10px] text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3] hover:bg-[#153667] transition-colors uppercase"
        >
          + New
        </button>
      </div>

      {/* Filters */}
      <div className="flex gap-1 p-2 border-b border-[rgba(117,170,252,0.1)]">
        {(["all", "active", "completed", "failed"] as const).map((f) => (
          <button
            key={f}
            onClick={() => setFilter(f)}
            className={`px-2 py-1 font-mono text-[10px] uppercase ${
              filter === f
                ? "text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3]"
                : "text-[#556677] hover:text-[#9bc3ff]"
            }`}
          >
            {f}
          </button>
        ))}
      </div>

      {/* List */}
      <div className="flex-1 overflow-y-auto">
        {loading ? (
          <div className="p-4 text-center">
            <p className="font-mono text-xs text-[#556677]">Loading...</p>
          </div>
        ) : filteredDirectives.length === 0 ? (
          <div className="p-4 text-center">
            <p className="font-mono text-xs text-[#556677]">No directives found</p>
          </div>
        ) : (
          filteredDirectives.map((d) => (
            <DirectiveListItem
              key={d.id}
              directive={d}
              selected={d.id === selectedId}
              onClick={() => onSelect(d.id)}
              onArchive={() => onArchive(d)}
            />
          ))
        )}
      </div>
    </div>
  );
}

interface DirectiveListItemProps {
  directive: DirectiveSummary;
  selected: boolean;
  onClick: () => void;
  onArchive: () => void;
}

function DirectiveListItem({ directive, selected, onClick, onArchive }: DirectiveListItemProps) {
  const progress = directive.totalSteps > 0
    ? Math.round((directive.completedSteps / directive.totalSteps) * 100)
    : 0;

  const statusColor = {
    draft: "text-[#556677]",
    planning: "text-yellow-400",
    active: "text-green-400",
    paused: "text-yellow-400",
    completed: "text-[#75aafc]",
    archived: "text-[#556677]",
    failed: "text-red-400",
  }[directive.status] || "text-[#556677]";

  const confidenceColor = {
    green: "bg-green-500",
    yellow: "bg-yellow-500",
    red: "bg-red-500",
  }[directive.currentConfidence !== null && directive.currentConfidence >= 0.8
    ? "green"
    : directive.currentConfidence !== null && directive.currentConfidence >= 0.5
    ? "yellow"
    : "red"] || "bg-[#556677]";

  return (
    <div
      onClick={onClick}
      className={`p-3 cursor-pointer border-b border-[rgba(117,170,252,0.1)] hover:bg-[rgba(117,170,252,0.05)] ${
        selected ? "bg-[rgba(117,170,252,0.1)]" : ""
      }`}
    >
      <div className="flex items-start justify-between gap-2">
        <div className="flex-1 min-w-0">
          <div className="font-mono text-sm text-[#dbe7ff] truncate">
            {directive.title || directive.goal.slice(0, 50)}
          </div>
          <div className="flex items-center gap-2 mt-1">
            <span className={`font-mono text-[10px] uppercase ${statusColor}`}>
              {directive.status}
            </span>
            <span className="font-mono text-[10px] text-[#556677]">
              {directive.completedSteps}/{directive.totalSteps} steps
            </span>
          </div>
        </div>
        <div className="flex flex-col items-end gap-1">
          {directive.currentConfidence !== null && (
            <div className={`w-2 h-2 rounded-full ${confidenceColor}`} title={`Confidence: ${Math.round(directive.currentConfidence * 100)}%`} />
          )}
          <button
            onClick={(e) => {
              e.stopPropagation();
              onArchive();
            }}
            className="font-mono text-[10px] text-[#556677] hover:text-red-400"
          >
            Archive
          </button>
        </div>
      </div>

      {/* Progress bar */}
      {directive.totalSteps > 0 && (
        <div className="mt-2 h-1 bg-[rgba(117,170,252,0.1)] overflow-hidden">
          <div
            className="h-full bg-[#75aafc] transition-all duration-300"
            style={{ width: `${progress}%` }}
          />
        </div>
      )}
    </div>
  );
}

// =============================================================================
// Directive Detail Component
// =============================================================================

interface DirectiveDetailProps {
  directive: DirectiveWithProgress;
  graph: DirectiveGraphResponse | null;
  loading: boolean;
  onBack: () => void;
  onRefresh: () => void;
  onStart: () => void;
  onPause: () => void;
  onResume: () => void;
  onStop: () => void;
}

function DirectiveDetail({
  directive,
  graph,
  loading,
  onBack,
  onRefresh,
  onStart,
  onPause,
  onResume,
  onStop,
}: DirectiveDetailProps) {
  const [activeTab, setActiveTab] = useState<"overview" | "chain" | "events" | "evaluations" | "approvals" | "verifiers">("overview");

  if (loading) {
    return (
      <div className="panel h-full flex items-center justify-center">
        <p className="font-mono text-xs text-[#556677]">Loading...</p>
      </div>
    );
  }

  const statusColor = {
    draft: "text-[#556677] bg-[#556677]/10 border-[#556677]/30",
    planning: "text-yellow-400 bg-yellow-400/10 border-yellow-400/30",
    active: "text-green-400 bg-green-400/10 border-green-400/30",
    paused: "text-yellow-400 bg-yellow-400/10 border-yellow-400/30",
    completed: "text-[#75aafc] bg-[#75aafc]/10 border-[#75aafc]/30",
    archived: "text-[#556677] bg-[#556677]/10 border-[#556677]/30",
    failed: "text-red-400 bg-red-400/10 border-red-400/30",
  }[directive.status] || "text-[#556677] bg-[#556677]/10 border-[#556677]/30";

  return (
    <div className="panel h-full flex flex-col overflow-hidden">
      {/* Header */}
      <div className="p-3 border-b border-[rgba(117,170,252,0.15)]">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <button
              onClick={onBack}
              className="font-mono text-xs text-[#556677] hover:text-[#9bc3ff]"
            >
              &larr; Back
            </button>
            <h2 className="font-mono text-sm text-[#dbe7ff]">
              {directive.title || directive.goal.slice(0, 50)}
            </h2>
            <span className={`px-2 py-0.5 font-mono text-[10px] uppercase border ${statusColor}`}>
              {directive.status}
            </span>
          </div>
          <div className="flex items-center gap-2">
            {directive.status === "draft" && (
              <button
                onClick={onStart}
                className="px-3 py-1 font-mono text-[10px] text-[#dbe7ff] bg-green-700 border border-green-600 hover:bg-green-600 uppercase"
              >
                Start
              </button>
            )}
            {directive.status === "active" && (
              <button
                onClick={onPause}
                className="px-3 py-1 font-mono text-[10px] text-[#dbe7ff] bg-yellow-700 border border-yellow-600 hover:bg-yellow-600 uppercase"
              >
                Pause
              </button>
            )}
            {directive.status === "paused" && (
              <button
                onClick={onResume}
                className="px-3 py-1 font-mono text-[10px] text-[#dbe7ff] bg-green-700 border border-green-600 hover:bg-green-600 uppercase"
              >
                Resume
              </button>
            )}
            {["active", "paused"].includes(directive.status) && (
              <button
                onClick={onStop}
                className="px-3 py-1 font-mono text-[10px] text-[#dbe7ff] bg-red-700 border border-red-600 hover:bg-red-600 uppercase"
              >
                Stop
              </button>
            )}
            <button
              onClick={onRefresh}
              className="px-3 py-1 font-mono text-[10px] text-[#9bc3ff] hover:text-[#dbe7ff]"
            >
              Refresh
            </button>
          </div>
        </div>
      </div>

      {/* Tabs */}
      <div className="flex gap-1 p-2 border-b border-[rgba(117,170,252,0.1)]">
        {(["overview", "chain", "events", "evaluations", "approvals", "verifiers"] as const).map((tab) => (
          <button
            key={tab}
            onClick={() => setActiveTab(tab)}
            className={`px-3 py-1.5 font-mono text-[10px] uppercase ${
              activeTab === tab
                ? "text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3]"
                : "text-[#556677] hover:text-[#9bc3ff]"
            }`}
          >
            {tab}
            {tab === "approvals" && directive.pendingApprovals.length > 0 && (
              <span className="ml-1 px-1 bg-yellow-500 text-black rounded text-[8px]">
                {directive.pendingApprovals.length}
              </span>
            )}
          </button>
        ))}
      </div>

      {/* Tab Content */}
      <div className="flex-1 overflow-y-auto p-4">
        {activeTab === "overview" && (
          <OverviewTab directive={directive} />
        )}
        {activeTab === "chain" && (
          <ChainTab directive={directive} graph={graph} />
        )}
        {activeTab === "events" && (
          <EventsTab directive={directive} />
        )}
        {activeTab === "evaluations" && (
          <EvaluationsTab directive={directive} />
        )}
        {activeTab === "approvals" && (
          <ApprovalsTab directive={directive} onRefresh={onRefresh} />
        )}
        {activeTab === "verifiers" && (
          <VerifiersTab directive={directive} />
        )}
      </div>
    </div>
  );
}

// =============================================================================
// Tab Components
// =============================================================================

function OverviewTab({ directive }: { directive: DirectiveWithProgress }) {
  return (
    <div className="space-y-6">
      {/* Goal */}
      <div>
        <h3 className="font-mono text-xs text-[#75aafc] uppercase mb-2">Goal</h3>
        <p className="font-mono text-sm text-[#dbe7ff] whitespace-pre-wrap">
          {directive.goal}
        </p>
      </div>

      {/* Progress */}
      <div>
        <h3 className="font-mono text-xs text-[#75aafc] uppercase mb-2">Progress</h3>
        <div className="grid grid-cols-3 gap-4">
          <div className="p-3 bg-[rgba(117,170,252,0.05)] border border-[rgba(117,170,252,0.15)]">
            <div className="font-mono text-2xl text-[#dbe7ff]">
              {directive.chain?.completedSteps || 0}
            </div>
            <div className="font-mono text-[10px] text-[#556677] uppercase">Completed Steps</div>
          </div>
          <div className="p-3 bg-[rgba(117,170,252,0.05)] border border-[rgba(117,170,252,0.15)]">
            <div className="font-mono text-2xl text-[#dbe7ff]">
              {directive.chain?.totalSteps || 0}
            </div>
            <div className="font-mono text-[10px] text-[#556677] uppercase">Total Steps</div>
          </div>
          <div className="p-3 bg-[rgba(117,170,252,0.05)] border border-[rgba(117,170,252,0.15)]">
            <div className="font-mono text-2xl text-[#dbe7ff]">
              {directive.chain?.currentConfidence != null
                ? `${Math.round((directive.chain?.currentConfidence ?? 0) * 100)}%`
                : "-"}
            </div>
            <div className="font-mono text-[10px] text-[#556677] uppercase">Confidence</div>
          </div>
        </div>
      </div>

      {/* Configuration */}
      <div>
        <h3 className="font-mono text-xs text-[#75aafc] uppercase mb-2">Configuration</h3>
        <div className="grid grid-cols-2 gap-2 text-sm">
          <div className="flex justify-between">
            <span className="font-mono text-[#556677]">Autonomy Level</span>
            <span className="font-mono text-[#dbe7ff]">{directive.autonomyLevel}</span>
          </div>
          <div className="flex justify-between">
            <span className="font-mono text-[#556677]">Max Rework Cycles</span>
            <span className="font-mono text-[#dbe7ff]">{directive.maxReworkCycles}</span>
          </div>
          <div className="flex justify-between">
            <span className="font-mono text-[#556677]">Green Threshold</span>
            <span className="font-mono text-[#dbe7ff]">{directive.confidenceThresholdGreen}</span>
          </div>
          <div className="flex justify-between">
            <span className="font-mono text-[#556677]">Yellow Threshold</span>
            <span className="font-mono text-[#dbe7ff]">{directive.confidenceThresholdYellow}</span>
          </div>
        </div>
      </div>

      {/* Repository */}
      {directive.repositoryUrl && (
        <div>
          <h3 className="font-mono text-xs text-[#75aafc] uppercase mb-2">Repository</h3>
          <p className="font-mono text-sm text-[#9bc3ff]">{directive.repositoryUrl}</p>
        </div>
      )}
    </div>
  );
}

// Step status colors for both list and DAG views
const stepStatusStyles: Record<StepStatus, { border: string; bg: string; text: string }> = {
  pending: { border: "#556677", bg: "#556677", text: "#556677" },
  ready: { border: "#3b82f6", bg: "#3b82f6", text: "#3b82f6" },
  running: { border: "#22c55e", bg: "#22c55e", text: "#22c55e" },
  evaluating: { border: "#eab308", bg: "#eab308", text: "#eab308" },
  passed: { border: "#75aafc", bg: "#75aafc", text: "#75aafc" },
  failed: { border: "#ef4444", bg: "#ef4444", text: "#ef4444" },
  rework: { border: "#f97316", bg: "#f97316", text: "#f97316" },
  skipped: { border: "#556677", bg: "#556677", text: "#556677" },
  blocked: { border: "#ef4444", bg: "#ef4444", text: "#ef4444" },
};

// Confidence level colors
const confidenceColors: Record<ConfidenceLevel, string> = {
  green: "#22c55e",
  yellow: "#eab308",
  red: "#ef4444",
};

// Node dimensions
const NODE_WIDTH = 180;
const NODE_HEIGHT = 70;

// Custom node component for steps
function StepNodeComponent({ data }: { data: DirectiveGraphNode & { selected?: boolean } }) {
  const styles = stepStatusStyles[data.status] || stepStatusStyles.pending;
  const isRunning = data.status === "running" || data.status === "evaluating";

  return (
    <div
      className={`rounded-lg border-2 bg-[#0a1628] overflow-hidden ${
        isRunning ? "animate-pulse" : ""
      }`}
      style={{
        width: NODE_WIDTH,
        height: NODE_HEIGHT,
        borderColor: styles.border,
        borderStyle: data.status === "pending" ? "dashed" : "solid",
      }}
    >
      <Handle
        type="target"
        position={Position.Top}
        className="!bg-[#75aafc] !w-3 !h-3 !border-2 !border-[#0a1628]"
      />

      {/* Status indicator bar */}
      <div className="h-1.5" style={{ backgroundColor: styles.bg }} />

      {/* Content */}
      <div className="p-2">
        <div className="flex items-center justify-between mb-1">
          <span className="font-mono text-xs text-[#dbe7ff] truncate flex-1">{data.name}</span>
          {data.confidenceScore !== null && data.confidenceLevel && (
            <div
              className="w-2 h-2 rounded-full flex-shrink-0 ml-1"
              style={{ backgroundColor: confidenceColors[data.confidenceLevel] }}
              title={`Confidence: ${Math.round(data.confidenceScore * 100)}%`}
            />
          )}
        </div>
        <div className="flex items-center justify-between">
          <span
            className="font-mono text-[10px] uppercase px-1.5 py-0.5 rounded"
            style={{
              color: styles.text,
              backgroundColor: `${styles.bg}20`,
            }}
          >
            {data.status}
          </span>
          <span className="font-mono text-[10px] text-[#8b949e]">{data.stepType}</span>
        </div>
      </div>

      <Handle
        type="source"
        position={Position.Bottom}
        className="!bg-[#f59e0b] !w-3 !h-3 !border-2 !border-[#0a1628]"
      />
    </div>
  );
}

// Node types for React Flow
const nodeTypes = {
  step: StepNodeComponent,
};

function ChainTab({ directive, graph }: { directive: DirectiveWithProgress; graph: DirectiveGraphResponse | null }) {
  const [viewMode, setViewMode] = useState<"dag" | "list">("dag");

  // Convert graph to React Flow nodes and edges
  const { nodes, edges } = useMemo(() => {
    if (!graph || !graph.nodes.length) {
      // Fallback: generate positions from directive.steps
      const stepNodes = directive.steps.map((step, index) => ({
        id: step.id,
        type: "step" as const,
        position: {
          x: (index % 3) * 220 + 50,
          y: Math.floor(index / 3) * 120 + 50,
        },
        data: {
          id: step.id,
          name: step.name,
          stepType: step.stepType,
          status: step.status,
          confidenceScore: step.confidenceScore,
          confidenceLevel: step.confidenceLevel,
          contractId: step.contractId,
          editorX: null,
          editorY: null,
        },
      }));

      // Build edges from dependencies
      const stepEdges: Edge[] = [];
      directive.steps.forEach((step) => {
        (step.dependsOn ?? []).forEach((depName) => {
          const depStep = directive.steps.find((s) => s.name === depName);
          if (depStep) {
            stepEdges.push({
              id: `${depStep.id}-${step.id}`,
              source: depStep.id,
              target: step.id,
              type: "smoothstep",
              markerEnd: { type: MarkerType.ArrowClosed, color: "#556677" },
              style: { stroke: "#556677", strokeWidth: 2 },
            });
          }
        });
      });

      return { nodes: stepNodes, edges: stepEdges };
    }

    // Use graph data
    const graphNodes = graph.nodes.map((node) => ({
      id: node.id,
      type: "step" as const,
      position: {
        x: node.editorX ?? 50,
        y: node.editorY ?? 50,
      },
      data: { ...node },
    }));

    const graphEdges: Edge[] = graph.edges.map((edge) => ({
      id: `${edge.source}-${edge.target}`,
      source: edge.source,
      target: edge.target,
      type: "smoothstep",
      markerEnd: { type: MarkerType.ArrowClosed, color: "#556677" },
      style: { stroke: "#556677", strokeWidth: 2 },
    }));

    return { nodes: graphNodes, edges: graphEdges };
  }, [graph, directive.steps]);

  if (!directive.chain) {
    return (
      <div className="text-center py-8">
        <p className="font-mono text-sm text-[#556677]">
          No chain generated yet. Start the directive to generate a chain.
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* Chain info header */}
      <div className="flex items-center justify-between p-3 bg-[rgba(117,170,252,0.05)] border border-[rgba(117,170,252,0.15)]">
        <div>
          <div className="font-mono text-sm text-[#dbe7ff]">{directive.chain.name}</div>
          <div className="font-mono text-[10px] text-[#556677]">Generation {directive.chain.generation}</div>
        </div>
        <div className="flex items-center gap-4">
          <div className="font-mono text-xs text-[#556677]">
            {directive.chain.completedSteps}/{directive.chain.totalSteps} steps
          </div>
          {/* View toggle */}
          <div className="flex border border-[rgba(117,170,252,0.2)]">
            <button
              onClick={() => setViewMode("dag")}
              className={`px-2 py-1 font-mono text-[10px] uppercase ${
                viewMode === "dag"
                  ? "bg-[rgba(117,170,252,0.2)] text-[#75aafc]"
                  : "text-[#556677] hover:text-[#75aafc]"
              }`}
            >
              DAG
            </button>
            <button
              onClick={() => setViewMode("list")}
              className={`px-2 py-1 font-mono text-[10px] uppercase ${
                viewMode === "list"
                  ? "bg-[rgba(117,170,252,0.2)] text-[#75aafc]"
                  : "text-[#556677] hover:text-[#75aafc]"
              }`}
            >
              List
            </button>
          </div>
        </div>
      </div>

      {viewMode === "dag" ? (
        /* DAG visualization */
        <div className="h-[400px] border border-[rgba(117,170,252,0.1)] rounded bg-[#050d18]">
          {directive.steps.length === 0 ? (
            <div className="flex items-center justify-center h-full">
              <p className="font-mono text-sm text-[#556677]">No steps in chain</p>
            </div>
          ) : (
            <ReactFlow
              nodes={nodes}
              edges={edges}
              nodeTypes={nodeTypes}
              fitView
              fitViewOptions={{ padding: 0.2 }}
              minZoom={0.5}
              maxZoom={1.5}
              defaultEdgeOptions={{
                type: "smoothstep",
                style: { stroke: "#556677", strokeWidth: 2 },
              }}
            >
              <Background variant={BackgroundVariant.Dots} gap={20} size={1} color="#1a2a3a" />
              <Controls className="!bg-[#0a1628] !border-[rgba(117,170,252,0.2)]" />
            </ReactFlow>
          )}
        </div>
      ) : (
        /* List view */
        <div className="space-y-2">
          <h3 className="font-mono text-xs text-[#75aafc] uppercase">Steps</h3>
          {directive.steps.length === 0 ? (
            <p className="font-mono text-sm text-[#556677]">No steps in chain</p>
          ) : (
            directive.steps.map((step) => {
              const styles = stepStatusStyles[step.status] || stepStatusStyles.pending;

              return (
                <div
                  key={step.id}
                  className="p-3 bg-[rgba(117,170,252,0.02)] border border-[rgba(117,170,252,0.1)]"
                >
                  <div className="flex items-center justify-between">
                    <div className="flex items-center gap-2">
                      <span className="font-mono text-sm text-[#dbe7ff]">{step.name}</span>
                      <span
                        className="px-1.5 py-0.5 font-mono text-[10px] uppercase border"
                        style={{ color: styles.text, borderColor: `${styles.border}50` }}
                      >
                        {step.status}
                      </span>
                      {step.confidenceScore !== null && (
                        <span className="font-mono text-[10px] text-[#556677]">
                          ({Math.round(step.confidenceScore * 100)}%)
                        </span>
                      )}
                    </div>
                    <div className="font-mono text-[10px] text-[#556677]">{step.stepType}</div>
                  </div>
                  {step.description && (
                    <p className="font-mono text-xs text-[#556677] mt-1">{step.description}</p>
                  )}
                  {step.dependsOn?.length > 0 && (
                    <div className="font-mono text-[10px] text-[#556677] mt-1">
                      Depends on: {step.dependsOn.join(", ")}
                    </div>
                  )}
                </div>
              );
            })
          )}
        </div>
      )}
    </div>
  );
}

function EventsTab({ directive }: { directive: DirectiveWithProgress }) {
  // Subscribe to real-time events via SSE
  const { events: streamEvents, isConnected, error: sseError } = useDirectiveEventSubscription(directive.id);

  // Combine initial events with streamed events (avoiding duplicates)
  const allEvents = useMemo(() => {
    const eventMap = new Map();
    // Add initial events first
    directive.recentEvents.forEach((e) => eventMap.set(e.id, e));
    // Add streamed events (will override any duplicates)
    streamEvents.forEach((e) => eventMap.set(e.id, e));
    // Sort by created_at descending (most recent first)
    return Array.from(eventMap.values()).sort(
      (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
    );
  }, [directive.recentEvents, streamEvents]);

  return (
    <div className="space-y-4">
      {/* Connection status */}
      <div className="flex items-center justify-between text-[10px] font-mono">
        <div className="flex items-center gap-2">
          <span className={isConnected ? "text-green-400" : "text-[#556677]"}>
            {isConnected ? "● Live" : "○ Connecting..."}
          </span>
          {sseError && <span className="text-red-400">{sseError}</span>}
        </div>
        <span className="text-[#556677]">{allEvents.length} events</span>
      </div>

      {/* Event list */}
      {allEvents.length === 0 ? (
        <div className="text-center py-8">
          <p className="font-mono text-sm text-[#556677]">No events yet</p>
        </div>
      ) : (
        <div className="space-y-2">
          {allEvents.map((event) => {
            const severityColors: Record<string, string> = {
              info: "text-[#75aafc]",
              warning: "text-yellow-400",
              error: "text-red-400",
              critical: "text-red-600",
            };
            const severityColor = severityColors[event.severity] || "text-[#556677]";

            return (
              <div
                key={event.id}
                className="p-3 bg-[rgba(117,170,252,0.02)] border border-[rgba(117,170,252,0.1)]"
              >
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-2">
                    <span className={`font-mono text-xs ${severityColor}`}>{event.eventType}</span>
                    <span className="font-mono text-[10px] text-[#556677]">{event.actorType}</span>
                  </div>
                  <span className="font-mono text-[10px] text-[#556677]">
                    {new Date(event.createdAt).toLocaleString()}
                  </span>
                </div>
                {event.eventData != null && (
                  <pre className="font-mono text-[10px] text-[#556677] mt-1 overflow-x-auto">
                    {JSON.stringify(event.eventData, null, 2)}
                  </pre>
                )}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

function EvaluationsTab({ directive: _directive }: { directive: DirectiveWithProgress }) {
  // TODO: Fetch evaluations separately
  return (
    <div className="text-center py-8">
      <p className="font-mono text-sm text-[#556677]">
        Evaluations will be shown here after steps are evaluated
      </p>
    </div>
  );
}

function ApprovalsTab({ directive, onRefresh }: { directive: DirectiveWithProgress; onRefresh: () => void }) {
  if (directive.pendingApprovals.length === 0) {
    return (
      <div className="text-center py-8">
        <p className="font-mono text-sm text-[#556677]">No pending approvals</p>
      </div>
    );
  }

  const handleApprove = async (approvalId: string) => {
    try {
      const { approveDirectiveRequest } = await import("../lib/api");
      await approveDirectiveRequest(directive.id, approvalId);
      onRefresh();
    } catch (err) {
      console.error("Failed to approve:", err);
    }
  };

  const handleDeny = async (approvalId: string) => {
    try {
      const { denyDirectiveRequest } = await import("../lib/api");
      await denyDirectiveRequest(directive.id, approvalId);
      onRefresh();
    } catch (err) {
      console.error("Failed to deny:", err);
    }
  };

  return (
    <div className="space-y-3">
      {directive.pendingApprovals.map((approval) => {
        const urgencyColor = {
          low: "text-[#556677]",
          normal: "text-[#75aafc]",
          high: "text-yellow-400",
          critical: "text-red-400",
        }[approval.urgency] || "text-[#556677]";

        return (
          <div
            key={approval.id}
            className="p-4 bg-[rgba(117,170,252,0.05)] border border-[rgba(117,170,252,0.2)]"
          >
            <div className="flex items-start justify-between">
              <div>
                <div className="flex items-center gap-2">
                  <span className="font-mono text-sm text-[#dbe7ff]">{approval.approvalType}</span>
                  <span className={`font-mono text-[10px] uppercase ${urgencyColor}`}>
                    {approval.urgency}
                  </span>
                </div>
                <p className="font-mono text-xs text-[#9bc3ff] mt-1">{approval.description}</p>
              </div>
              <div className="flex gap-2">
                <button
                  onClick={() => handleApprove(approval.id)}
                  className="px-3 py-1 font-mono text-[10px] text-[#dbe7ff] bg-green-700 border border-green-600 hover:bg-green-600 uppercase"
                >
                  Approve
                </button>
                <button
                  onClick={() => handleDeny(approval.id)}
                  className="px-3 py-1 font-mono text-[10px] text-[#dbe7ff] bg-red-700 border border-red-600 hover:bg-red-600 uppercase"
                >
                  Deny
                </button>
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

function VerifiersTab({ directive: _directive }: { directive: DirectiveWithProgress }) {
  // TODO: Fetch verifiers separately
  return (
    <div className="text-center py-8">
      <p className="font-mono text-sm text-[#556677]">
        Verifiers will be shown here. Use auto-detect to find available verifiers.
      </p>
    </div>
  );
}

// =============================================================================
// Create Directive Modal
// =============================================================================

interface CreateDirectiveModalProps {
  onSubmit: (goal: string, repositoryUrl: string | undefined, autonomyLevel: AutonomyLevel) => void;
  onCancel: () => void;
}

function CreateDirectiveModal({ onSubmit, onCancel }: CreateDirectiveModalProps) {
  const [goal, setGoal] = useState("");
  const [repositoryUrl, setRepositoryUrl] = useState("");
  const [autonomyLevel, setAutonomyLevel] = useState<AutonomyLevel>("guardrails");
  const [suggestions, setSuggestions] = useState<RepositoryHistoryEntry[]>([]);
  const [showSuggestions, setShowSuggestions] = useState(false);

  // Load suggestions
  useEffect(() => {
    getRepositorySuggestions("remote", undefined, 5)
      .then((res) => {
        setSuggestions(res.entries);
      })
      .catch(() => {
        setSuggestions([]);
      });
  }, []);

  const handleSubmit = () => {
    if (goal.trim()) {
      onSubmit(goal.trim(), repositoryUrl.trim() || undefined, autonomyLevel);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4">
      <div className="w-full max-w-lg p-6 bg-[#0a1628] border border-[rgba(117,170,252,0.3)] max-h-[90vh] overflow-y-auto">
        <h3 className="font-mono text-sm text-[#75aafc] uppercase mb-4">
          Create Directive
        </h3>

        <div className="space-y-4">
          {/* Goal */}
          <div>
            <label className="block font-mono text-xs text-[#8b949e] uppercase mb-1">
              Goal *
            </label>
            <textarea
              value={goal}
              onChange={(e) => setGoal(e.target.value)}
              placeholder="Describe what you want to accomplish..."
              rows={3}
              className="w-full px-3 py-2 bg-[#0d1b2d] border border-[#3f6fb3] text-[#dbe7ff] font-mono text-sm focus:outline-none focus:border-[#75aafc] resize-none"
              autoFocus
            />
          </div>

          {/* Repository URL */}
          <div>
            <label className="block font-mono text-xs text-[#8b949e] uppercase mb-1">
              Repository URL (optional)
            </label>
            <div className="relative">
              <input
                type="text"
                value={repositoryUrl}
                onChange={(e) => setRepositoryUrl(e.target.value)}
                onFocus={() => suggestions.length > 0 && setShowSuggestions(true)}
                onBlur={() => setTimeout(() => setShowSuggestions(false), 200)}
                placeholder="https://github.com/owner/repo"
                className="w-full px-3 py-2 bg-[#0d1b2d] border border-[#3f6fb3] text-[#dbe7ff] font-mono text-sm focus:outline-none focus:border-[#75aafc]"
              />
              {showSuggestions && suggestions.length > 0 && (
                <div className="absolute top-full left-0 right-0 mt-1 border border-[rgba(117,170,252,0.2)] bg-[#0a1525] max-h-32 overflow-y-auto z-10">
                  {suggestions.map((s) => (
                    <button
                      key={s.id}
                      type="button"
                      onClick={() => {
                        setRepositoryUrl(s.repositoryUrl || "");
                        setShowSuggestions(false);
                      }}
                      className="w-full text-left px-3 py-2 font-mono text-xs hover:bg-[rgba(117,170,252,0.1)] border-b border-[rgba(117,170,252,0.1)] last:border-b-0"
                    >
                      <div className="text-[#9bc3ff] truncate">{s.name}</div>
                      <div className="text-[10px] text-[#556677] truncate">{s.repositoryUrl}</div>
                    </button>
                  ))}
                </div>
              )}
            </div>
          </div>

          {/* Autonomy Level */}
          <div>
            <label className="block font-mono text-xs text-[#8b949e] uppercase mb-2">
              Autonomy Level
            </label>
            <div className="flex gap-2">
              {(["full_auto", "guardrails", "manual"] as const).map((level) => (
                <button
                  key={level}
                  type="button"
                  onClick={() => setAutonomyLevel(level)}
                  className={`flex-1 px-3 py-2 font-mono text-xs uppercase ${
                    autonomyLevel === level
                      ? "text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3]"
                      : "text-[#556677] border border-[rgba(117,170,252,0.2)] hover:border-[#3f6fb3]"
                  }`}
                >
                  {level.replace("_", " ")}
                </button>
              ))}
            </div>
            <p className="font-mono text-[10px] text-[#556677] mt-1">
              {autonomyLevel === "full_auto" && "Automatic progression without approval gates"}
              {autonomyLevel === "guardrails" && "Request approval for yellow/red confidence scores"}
              {autonomyLevel === "manual" && "Request approval for all step completions"}
            </p>
          </div>

          <p className="font-mono text-xs text-[#8b949e]">
            A directive is a top-level goal that generates a chain of steps. Each step spawns
            contracts that are verified before progression.
          </p>

          {/* Actions */}
          <div className="flex gap-2 justify-end pt-2">
            <button
              onClick={onCancel}
              className="px-4 py-2 font-mono text-xs text-[#9bc3ff] hover:text-[#dbe7ff] transition-colors"
            >
              Cancel
            </button>
            <button
              onClick={handleSubmit}
              disabled={!goal.trim()}
              className="px-4 py-2 font-mono text-xs text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3] hover:bg-[#153667] transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
            >
              Create
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
