import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Plus, Trash2 } from "lucide-react";
import { useConfigStore } from "@/stores/configStore";
import type { EarlyStopCondition, EarlyStopType, TopologyHookConfig, TopologyHookType } from "@/types/execution";

export function RunnerConfigForm() {
  const { runnerConfig, updateRunnerConfig } = useConfigStore();

  // ── Early-stop helpers ──────────────────────────────────────────────
  const addEarlyStop = () => {
    updateRunnerConfig({
      early_stop_conditions: [
        ...runnerConfig.early_stop_conditions,
        { type: "keyword", keyword: "FINAL ANSWER" },
      ],
    });
  };

  const removeEarlyStop = (idx: number) => {
    updateRunnerConfig({
      early_stop_conditions: runnerConfig.early_stop_conditions.filter((_, i) => i !== idx),
    });
  };

  const updateEarlyStop = (idx: number, patch: Partial<EarlyStopCondition>) => {
    updateRunnerConfig({
      early_stop_conditions: runnerConfig.early_stop_conditions.map((c, i) =>
        i === idx ? { ...c, ...patch } : c
      ),
    });
  };

  // ── Topology-hook helpers ───────────────────────────────────────────
  const addTopologyHook = () => {
    updateRunnerConfig({
      topology_hooks: [
        ...runnerConfig.topology_hooks,
        { type: "stop_on_keyword", keyword: "TASK_COMPLETE" },
      ],
    });
  };

  const removeTopologyHook = (idx: number) => {
    updateRunnerConfig({
      topology_hooks: runnerConfig.topology_hooks.filter((_, i) => i !== idx),
    });
  };

  const updateTopologyHook = (idx: number, patch: Partial<TopologyHookConfig>) => {
    updateRunnerConfig({
      topology_hooks: runnerConfig.topology_hooks.map((h, i) =>
        i === idx ? { ...h, ...patch } : h
      ),
    });
  };

  const hasDynamicFeatures =
    runnerConfig.enable_dynamic_topology ||
    runnerConfig.early_stop_conditions.length > 0 ||
    runnerConfig.topology_hooks.length > 0;

  return (
    <div className="space-y-6">
      {/* ── General settings ─────────────────────────────────────── */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Runner Configuration</CardTitle>
          <CardDescription>Configure the MACPRunner execution settings.</CardDescription>
        </CardHeader>
        <CardContent className="grid gap-4 sm:grid-cols-2">
          <div className="space-y-2">
            <Label>Timeout (seconds)</Label>
            <Input
              type="number"
              value={runnerConfig.timeout}
              onChange={(e) => updateRunnerConfig({ timeout: parseFloat(e.target.value) || 60 })}
            />
          </div>

          <div className="space-y-2">
            <Label>Max Retries</Label>
            <Input
              type="number"
              value={runnerConfig.max_retries}
              onChange={(e) => updateRunnerConfig({ max_retries: parseInt(e.target.value) || 2 })}
            />
          </div>

          <div className="space-y-2">
            <Label>Max Parallel Size</Label>
            <Input
              type="number"
              value={runnerConfig.max_parallel_size}
              onChange={(e) => updateRunnerConfig({ max_parallel_size: parseInt(e.target.value) || 5 })}
            />
          </div>

          <div className="space-y-2">
            <Label>Max Tool Iterations</Label>
            <Input
              type="number"
              value={runnerConfig.max_tool_iterations}
              onChange={(e) => updateRunnerConfig({ max_tool_iterations: parseInt(e.target.value) || 3 })}
            />
          </div>

          <div className="space-y-2">
            <Label>Memory Context Limit</Label>
            <Input
              type="number"
              value={runnerConfig.memory_context_limit}
              onChange={(e) => updateRunnerConfig({ memory_context_limit: parseInt(e.target.value) || 5 })}
            />
          </div>

          <div className="sm:col-span-2 flex items-start justify-between gap-4 rounded-md border p-3">
            <div className="space-y-0.5">
              <Label>Adaptive Mode</Label>
              <p className="text-xs text-muted-foreground">Weight-aware scheduling that dynamically reorders agents based on edge weights and intermediate results.</p>
            </div>
            <Switch
              className="shrink-0"
              checked={runnerConfig.adaptive}
              onCheckedChange={(v) => updateRunnerConfig({ adaptive: v })}
            />
          </div>

          <div className="sm:col-span-2 flex items-start justify-between gap-4 rounded-md border p-3">
            <div className="space-y-0.5">
              <Label>Enable Parallel</Label>
              <p className="text-xs text-muted-foreground">Allow agents without dependencies to execute concurrently, improving throughput for fan-out topologies.</p>
            </div>
            <Switch
              className="shrink-0"
              checked={runnerConfig.enable_parallel}
              onCheckedChange={(v) => updateRunnerConfig({ enable_parallel: v })}
            />
          </div>

          <div className="sm:col-span-2 flex items-start justify-between gap-4 rounded-md border p-3">
            <div className="space-y-0.5">
              <Label>Enable Memory</Label>
              <p className="text-xs text-muted-foreground">Activate shared memory so agents can read and write persistent context across execution steps.</p>
            </div>
            <Switch
              className="shrink-0"
              checked={runnerConfig.enable_memory}
              onCheckedChange={(v) => updateRunnerConfig({ enable_memory: v })}
            />
          </div>

          <div className="sm:col-span-2 flex items-start justify-between gap-4 rounded-md border p-3">
            <div className="space-y-0.5">
              <Label>Dynamic Topology</Label>
              <p className="text-xs text-muted-foreground">Enable runtime graph modifications via early stopping conditions and topology hooks defined below.</p>
            </div>
            <Switch
              className="shrink-0"
              checked={hasDynamicFeatures}
              onCheckedChange={(v) => updateRunnerConfig({ enable_dynamic_topology: v })}
            />
          </div>

          <div className="sm:col-span-2 flex items-start justify-between gap-4 rounded-md border p-3">
            <div className="space-y-0.5">
              <Label>Broadcast Task to All</Label>
              <p className="text-xs text-muted-foreground">Send the task query to every agent in the graph, not just the start node. Useful when all agents need full context.</p>
            </div>
            <Switch
              className="shrink-0"
              checked={runnerConfig.broadcast_task_to_all}
              onCheckedChange={(v) => updateRunnerConfig({ broadcast_task_to_all: v })}
            />
          </div>
        </CardContent>
      </Card>

      {/* ── Early Stopping ───────────────────────────────────────── */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Early Stopping</CardTitle>
          <CardDescription>
            Halt execution when specific conditions are met. Saves tokens by stopping early.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-3">
          {runnerConfig.early_stop_conditions.map((cond, idx) => (
            <div key={idx} className="flex items-end gap-2 rounded-md border p-3">
              <div className="space-y-1 w-40">
                <Label className="text-xs">Type</Label>
                <Select
                  value={cond.type}
                  onValueChange={(v) => updateEarlyStop(idx, { type: v as EarlyStopType })}
                >
                  <SelectTrigger className="h-8 text-xs">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="keyword">Keyword</SelectItem>
                    <SelectItem value="token_limit">Token Limit</SelectItem>
                    <SelectItem value="agent_count">Agent Count</SelectItem>
                  </SelectContent>
                </Select>
              </div>

              <div className="flex-1 space-y-1">
                {cond.type === "keyword" && (
                  <>
                    <Label className="text-xs">Keyword</Label>
                    <Input
                      className="h-8 text-xs"
                      placeholder="FINAL ANSWER"
                      value={cond.keyword || ""}
                      onChange={(e) => updateEarlyStop(idx, { keyword: e.target.value })}
                    />
                  </>
                )}
                {cond.type === "token_limit" && (
                  <>
                    <Label className="text-xs">Max Tokens</Label>
                    <Input
                      className="h-8 text-xs"
                      type="number"
                      placeholder="10000"
                      value={cond.max_tokens ?? ""}
                      onChange={(e) => updateEarlyStop(idx, { max_tokens: parseInt(e.target.value) || null })}
                    />
                  </>
                )}
                {cond.type === "agent_count" && (
                  <>
                    <Label className="text-xs">Max Agents</Label>
                    <Input
                      className="h-8 text-xs"
                      type="number"
                      placeholder="5"
                      value={cond.max_agents ?? ""}
                      onChange={(e) => updateEarlyStop(idx, { max_agents: parseInt(e.target.value) || null })}
                    />
                  </>
                )}
              </div>

              <Button variant="ghost" size="icon" className="h-8 w-8 shrink-0" onClick={() => removeEarlyStop(idx)}>
                <Trash2 className="h-3.5 w-3.5 text-muted-foreground" />
              </Button>
            </div>
          ))}

          <Button variant="outline" size="sm" className="gap-1" onClick={addEarlyStop}>
            <Plus className="h-3.5 w-3.5" />
            Add Condition
          </Button>
        </CardContent>
      </Card>

      {/* ── Topology Hooks ───────────────────────────────────────── */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Topology Hooks</CardTitle>
          <CardDescription>
            Dynamically modify the graph during execution based on intermediate results.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-3">
          {runnerConfig.topology_hooks.map((hook, idx) => (
            <div key={idx} className="rounded-md border p-3 space-y-2">
              <div className="flex items-end gap-2">
                <div className="space-y-1 w-52">
                  <Label className="text-xs">Hook Type</Label>
                  <Select
                    value={hook.type}
                    onValueChange={(v) => {
                      const patch: Partial<TopologyHookConfig> = { type: v as TopologyHookType };
                      if (v === "stop_on_keyword") patch.keyword = "TASK_COMPLETE";
                      if (v === "skip_on_token_budget") patch.token_threshold = 5000;
                      if (v === "force_reviewer_on_error") patch.reviewer_agent_id = "";
                      if (v === "insert_chain_on_keyword") { patch.keyword = "NEEDS_REVIEW"; patch.source_agent = ""; patch.target_agent = ""; }
                      if (v === "add_edge_on_keyword") { patch.keyword = "ESCALATE"; patch.source_agent = ""; patch.target_agent = ""; patch.weight = 1.0; }
                      if (v === "redirect_end_on_keyword") { patch.keyword = "REDIRECT"; patch.target_agent = ""; }
                      if (v === "skip_agent_on_keyword") { patch.keyword = "SKIP"; patch.target_agent = ""; }
                      updateTopologyHook(idx, patch);
                    }}
                  >
                    <SelectTrigger className="h-8 text-xs">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="stop_on_keyword">Stop on keyword</SelectItem>
                      <SelectItem value="skip_on_token_budget">Skip on token budget</SelectItem>
                      <SelectItem value="force_reviewer_on_error">Force reviewer on error</SelectItem>
                      <SelectItem value="insert_chain_on_keyword">Insert chain on keyword</SelectItem>
                      <SelectItem value="add_edge_on_keyword">Add edge on keyword</SelectItem>
                      <SelectItem value="redirect_end_on_keyword">Redirect end on keyword</SelectItem>
                      <SelectItem value="skip_agent_on_keyword">Skip agent on keyword</SelectItem>
                    </SelectContent>
                  </Select>
                </div>

                <div className="flex-1" />

                <Button variant="ghost" size="icon" className="h-8 w-8 shrink-0" onClick={() => removeTopologyHook(idx)}>
                  <Trash2 className="h-3.5 w-3.5 text-muted-foreground" />
                </Button>
              </div>

              {/* Parameters row */}
              <div className="grid gap-2 sm:grid-cols-2">
                {/* Keyword field — used by most hook types */}
                {["stop_on_keyword", "insert_chain_on_keyword", "add_edge_on_keyword", "redirect_end_on_keyword", "skip_agent_on_keyword"].includes(hook.type) && (
                  <div className="space-y-1">
                    <Label className="text-xs">Keyword</Label>
                    <Input
                      className="h-8 text-xs"
                      placeholder="TASK_COMPLETE"
                      value={hook.keyword || ""}
                      onChange={(e) => updateTopologyHook(idx, { keyword: e.target.value })}
                    />
                  </div>
                )}

                {/* Token threshold */}
                {hook.type === "skip_on_token_budget" && (
                  <div className="space-y-1">
                    <Label className="text-xs">Token Threshold</Label>
                    <Input
                      className="h-8 text-xs"
                      type="number"
                      placeholder="5000"
                      value={hook.token_threshold ?? ""}
                      onChange={(e) => updateTopologyHook(idx, { token_threshold: parseInt(e.target.value) || null })}
                    />
                  </div>
                )}

                {/* Reviewer agent */}
                {hook.type === "force_reviewer_on_error" && (
                  <div className="space-y-1">
                    <Label className="text-xs">Reviewer Agent ID</Label>
                    <Input
                      className="h-8 text-xs"
                      placeholder="reviewer"
                      value={hook.reviewer_agent_id || ""}
                      onChange={(e) => updateTopologyHook(idx, { reviewer_agent_id: e.target.value })}
                    />
                  </div>
                )}

                {/* Source agent — for insert_chain and add_edge */}
                {["insert_chain_on_keyword", "add_edge_on_keyword"].includes(hook.type) && (
                  <div className="space-y-1">
                    <Label className="text-xs">Source Agent ID</Label>
                    <Input
                      className="h-8 text-xs"
                      placeholder="agent_a"
                      value={hook.source_agent || ""}
                      onChange={(e) => updateTopologyHook(idx, { source_agent: e.target.value })}
                    />
                  </div>
                )}

                {/* Target agent — for insert_chain, add_edge, redirect_end, skip_agent */}
                {["insert_chain_on_keyword", "add_edge_on_keyword", "redirect_end_on_keyword", "skip_agent_on_keyword"].includes(hook.type) && (
                  <div className="space-y-1">
                    <Label className="text-xs">Target Agent ID</Label>
                    <Input
                      className="h-8 text-xs"
                      placeholder="agent_b"
                      value={hook.target_agent || ""}
                      onChange={(e) => updateTopologyHook(idx, { target_agent: e.target.value })}
                    />
                  </div>
                )}

                {/* Weight — for add_edge */}
                {hook.type === "add_edge_on_keyword" && (
                  <div className="space-y-1">
                    <Label className="text-xs">Edge Weight</Label>
                    <Input
                      className="h-8 text-xs"
                      type="number"
                      step="0.1"
                      min="0"
                      max="1"
                      placeholder="1.0"
                      value={hook.weight ?? 1.0}
                      onChange={(e) => updateTopologyHook(idx, { weight: parseFloat(e.target.value) || 1.0 })}
                    />
                  </div>
                )}
              </div>
            </div>
          ))}

          <Button variant="outline" size="sm" className="gap-1" onClick={addTopologyHook}>
            <Plus className="h-3.5 w-3.5" />
            Add Hook
          </Button>
        </CardContent>
      </Card>
    </div>
  );
}
