import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useDialog } from "../context/DialogContext";
import { useCompany } from "../context/CompanyContext";
import { companiesApi } from "../api/companies";
import { goalsApi } from "../api/goals";
import { agentsApi } from "../api/agents";
import { issuesApi } from "../api/issues";
import { queryKeys } from "../lib/queryKeys";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Button } from "@/components/ui/button";
import { cn } from "../lib/utils";
import {
  Building2,
  Bot,
  ListTodo,
  Rocket,
  ArrowLeft,
  ArrowRight,
  Terminal,
  Globe,
  Sparkles,
  Check,
  Loader2,
  FolderOpen,
  ChevronDown,
} from "lucide-react";

type Step = 1 | 2 | 3 | 4;
type AdapterType = "claude_local" | "process" | "http";

export function OnboardingWizard() {
  const { onboardingOpen, closeOnboarding } = useDialog();
  const { setSelectedCompanyId } = useCompany();
  const queryClient = useQueryClient();
  const navigate = useNavigate();

  const [step, setStep] = useState<Step>(1);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [modelOpen, setModelOpen] = useState(false);

  // Step 1
  const [companyName, setCompanyName] = useState("");
  const [companyGoal, setCompanyGoal] = useState("");

  // Step 2
  const [agentName, setAgentName] = useState("CEO");
  const [adapterType, setAdapterType] = useState<AdapterType>("claude_local");
  const [cwd, setCwd] = useState("");
  const [model, setModel] = useState("");
  const [command, setCommand] = useState("");
  const [args, setArgs] = useState("");
  const [url, setUrl] = useState("");

  // Step 3
  const [taskTitle, setTaskTitle] = useState("Create your CEO HEARTBEAT.md");
  const [taskDescription, setTaskDescription] = useState("You're the CEO of the company, make sure you have a file agents/ceo/HEARTBEAT.md that tells you your core loop. You MUST use the Paperclip SKILL.");

  // Created entity IDs
  const [createdCompanyId, setCreatedCompanyId] = useState<string | null>(null);
  const [createdAgentId, setCreatedAgentId] = useState<string | null>(null);

  const { data: adapterModels } = useQuery({
    queryKey: ["adapter-models", adapterType],
    queryFn: () => agentsApi.adapterModels(adapterType),
    enabled: onboardingOpen && step === 2,
  });

  const selectedModel = (adapterModels ?? []).find((m) => m.id === model);

  function reset() {
    setStep(1);
    setLoading(false);
    setError(null);
    setCompanyName("");
    setCompanyGoal("");
    setAgentName("CEO");
    setAdapterType("claude_local");
    setCwd("");
    setModel("");
    setCommand("");
    setArgs("");
    setUrl("");
    setTaskTitle("Create your CEO HEARTBEAT.md");
    setTaskDescription("You're the CEO of the company, make sure you have a file agents/ceo/HEARTBEAT.md that tells you your core loop. You MUST use the Paperclip SKILL.");
    setCreatedCompanyId(null);
    setCreatedAgentId(null);
  }

  function buildAdapterConfig(): Record<string, unknown> {
    if (adapterType === "claude_local") {
      return {
        ...(cwd ? { cwd } : {}),
        ...(model ? { model } : {}),
        timeoutSec: 900,
        graceSec: 15,
        maxTurnsPerRun: 80,
        dangerouslySkipPermissions: true,
      };
    }
    if (adapterType === "process") {
      return {
        ...(command ? { command } : {}),
        args: args
          .split(",")
          .map((s) => s.trim())
          .filter(Boolean),
        timeoutSec: 900,
        graceSec: 15,
      };
    }
    // http
    return {
      ...(url ? { url } : {}),
      method: "POST",
      timeoutMs: 15000,
    };
  }

  async function handleStep1Next() {
    setLoading(true);
    setError(null);
    try {
      const company = await companiesApi.create({ name: companyName.trim() });
      setCreatedCompanyId(company.id);
      setSelectedCompanyId(company.id);
      queryClient.invalidateQueries({ queryKey: queryKeys.companies.all });

      if (companyGoal.trim()) {
        await goalsApi.create(company.id, {
          title: companyGoal.trim(),
          level: "company",
          status: "active",
        });
        queryClient.invalidateQueries({ queryKey: queryKeys.goals.list(company.id) });
      }

      setStep(2);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to create company");
    } finally {
      setLoading(false);
    }
  }

  async function handleStep2Next() {
    if (!createdCompanyId) return;
    setLoading(true);
    setError(null);
    try {
      const agent = await agentsApi.create(createdCompanyId, {
        name: agentName.trim(),
        role: "ceo",
        adapterType,
        adapterConfig: buildAdapterConfig(),
        runtimeConfig: {
          heartbeat: {
            enabled: true,
            intervalSec: 300,
            wakeOnAssignment: true,
            wakeOnOnDemand: true,
            wakeOnAutomation: true,
            cooldownSec: 10,
          },
        },
      });
      setCreatedAgentId(agent.id);
      queryClient.invalidateQueries({
        queryKey: queryKeys.agents.list(createdCompanyId),
      });
      setStep(3);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to create agent");
    } finally {
      setLoading(false);
    }
  }

  async function handleStep3Next() {
    if (!createdCompanyId || !createdAgentId) return;
    setLoading(true);
    setError(null);
    try {
      await issuesApi.create(createdCompanyId, {
        title: taskTitle.trim(),
        ...(taskDescription.trim() ? { description: taskDescription.trim() } : {}),
        assigneeAgentId: createdAgentId,
        status: "todo",
      });
      queryClient.invalidateQueries({
        queryKey: queryKeys.issues.list(createdCompanyId),
      });
      setStep(4);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to create task");
    } finally {
      setLoading(false);
    }
  }

  async function handleLaunch() {
    if (!createdAgentId) return;
    setLoading(true);
    setError(null);
    try {
      await agentsApi.invoke(createdAgentId);
    } catch {
      // Agent may already be running from auto-wake — that's fine
    }
    setLoading(false);
    reset();
    closeOnboarding();
    navigate(`/agents/${createdAgentId}`);
  }

  function handleKeyDown(e: React.KeyboardEvent) {
    if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
      e.preventDefault();
      if (step === 1 && companyName.trim()) handleStep1Next();
      else if (step === 2 && agentName.trim()) handleStep2Next();
      else if (step === 3 && taskTitle.trim()) handleStep3Next();
      else if (step === 4) handleLaunch();
    }
  }

  const stepIcons = [Building2, Bot, ListTodo, Rocket];

  return (
    <Dialog
      open={onboardingOpen}
      onOpenChange={(open) => {
        if (!open) {
          reset();
          closeOnboarding();
        }
      }}
    >
      <DialogContent
        showCloseButton={false}
        className="p-0 gap-0 overflow-hidden sm:max-w-lg"
        onKeyDown={handleKeyDown}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-4 py-2.5 border-b border-border">
          <div className="flex items-center gap-2 text-sm">
            <Sparkles className="h-4 w-4 text-muted-foreground" />
            <span className="font-medium">Get Started</span>
            <span className="text-muted-foreground/60">
              Step {step} of 4
            </span>
          </div>
          <div className="flex items-center gap-1.5">
            {[1, 2, 3, 4].map((s) => (
              <div
                key={s}
                className={cn(
                  "h-1.5 w-6 rounded-full transition-colors",
                  s < step
                    ? "bg-green-500"
                    : s === step
                      ? "bg-foreground"
                      : "bg-muted"
                )}
              />
            ))}
          </div>
        </div>

        {/* Content */}
        <div className="overflow-y-auto max-h-[60vh]">
          {step === 1 && (
            <div className="p-4 space-y-4">
              <div className="flex items-center gap-3 mb-2">
                <div className="bg-muted/50 p-2">
                  <Building2 className="h-5 w-5 text-muted-foreground" />
                </div>
                <div>
                  <h3 className="font-medium">Name your company</h3>
                  <p className="text-xs text-muted-foreground">
                    This is the organization your agents will work for.
                  </p>
                </div>
              </div>
              <div>
                <label className="text-xs text-muted-foreground mb-1 block">
                  Company name
                </label>
                <input
                  className="w-full rounded-md border border-border bg-transparent px-3 py-2 text-sm outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50"
                  placeholder="Acme Corp"
                  value={companyName}
                  onChange={(e) => setCompanyName(e.target.value)}
                  autoFocus
                />
              </div>
              <div>
                <label className="text-xs text-muted-foreground mb-1 block">
                  Mission / goal (optional)
                </label>
                <textarea
                  className="w-full rounded-md border border-border bg-transparent px-3 py-2 text-sm outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50 resize-none min-h-[60px]"
                  placeholder="What is this company trying to achieve?"
                  value={companyGoal}
                  onChange={(e) => setCompanyGoal(e.target.value)}
                />
              </div>
            </div>
          )}

          {step === 2 && (
            <div className="p-4 space-y-4">
              <div className="flex items-center gap-3 mb-2">
                <div className="bg-muted/50 p-2">
                  <Bot className="h-5 w-5 text-muted-foreground" />
                </div>
                <div>
                  <h3 className="font-medium">Create your first agent</h3>
                  <p className="text-xs text-muted-foreground">
                    Choose how this agent will run tasks.
                  </p>
                </div>
              </div>
              <div>
                <label className="text-xs text-muted-foreground mb-1 block">
                  Agent name
                </label>
                <input
                  className="w-full rounded-md border border-border bg-transparent px-3 py-2 text-sm outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50"
                  placeholder="CEO"
                  value={agentName}
                  onChange={(e) => setAgentName(e.target.value)}
                  autoFocus
                />
              </div>

              {/* Adapter type radio cards */}
              <div>
                <label className="text-xs text-muted-foreground mb-2 block">
                  Adapter type
                </label>
                <div className="grid grid-cols-3 gap-2">
                  {([
                    {
                      value: "claude_local" as const,
                      label: "Claude Code",
                      icon: Sparkles,
                      desc: "Local Claude agent",
                    },
                    {
                      value: "process" as const,
                      label: "Shell Command",
                      icon: Terminal,
                      desc: "Run a process",
                    },
                    {
                      value: "http" as const,
                      label: "HTTP Webhook",
                      icon: Globe,
                      desc: "Call an endpoint",
                    },
                  ] as const).map((opt) => (
                    <button
                      key={opt.value}
                      className={cn(
                        "flex flex-col items-center gap-1.5 rounded-md border p-3 text-xs transition-colors",
                        adapterType === opt.value
                          ? "border-foreground bg-accent"
                          : "border-border hover:bg-accent/50"
                      )}
                      onClick={() => setAdapterType(opt.value)}
                    >
                      <opt.icon className="h-4 w-4" />
                      <span className="font-medium">{opt.label}</span>
                      <span className="text-muted-foreground text-[10px]">
                        {opt.desc}
                      </span>
                    </button>
                  ))}
                </div>
              </div>

              {/* Conditional adapter fields */}
              {adapterType === "claude_local" && (
                <div className="space-y-3">
                  <div>
                    <label className="text-xs text-muted-foreground mb-1 block">
                      Working directory
                    </label>
                    <div className="flex items-center gap-2 rounded-md border border-border px-2.5 py-1.5">
                      <FolderOpen className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
                      <input
                        className="w-full bg-transparent outline-none text-sm font-mono placeholder:text-muted-foreground/50"
                        placeholder="/path/to/project"
                        value={cwd}
                        onChange={(e) => setCwd(e.target.value)}
                      />
                      <button
                        type="button"
                        className="inline-flex items-center rounded-md border border-border px-2 py-0.5 text-xs text-muted-foreground hover:bg-accent/50 transition-colors shrink-0"
                        onClick={async () => {
                          try {
                            // @ts-expect-error -- showDirectoryPicker is not in all TS lib defs yet
                            const handle = await window.showDirectoryPicker({ mode: "read" });
                            setCwd(handle.name);
                          } catch {
                            // user cancelled or API unsupported
                          }
                        }}
                      >
                        Choose
                      </button>
                    </div>
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground mb-1 block">
                      Model
                    </label>
                    <Popover open={modelOpen} onOpenChange={setModelOpen}>
                      <PopoverTrigger asChild>
                        <button className="inline-flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-sm hover:bg-accent/50 transition-colors w-full justify-between">
                          <span className={cn(!model && "text-muted-foreground")}>
                            {selectedModel ? selectedModel.label : model || "Default"}
                          </span>
                          <ChevronDown className="h-3 w-3 text-muted-foreground" />
                        </button>
                      </PopoverTrigger>
                      <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-1" align="start">
                        <button
                          className={cn(
                            "flex items-center gap-2 w-full px-2 py-1.5 text-sm rounded hover:bg-accent/50",
                            !model && "bg-accent"
                          )}
                          onClick={() => { setModel(""); setModelOpen(false); }}
                        >
                          Default
                        </button>
                        {(adapterModels ?? []).map((m) => (
                          <button
                            key={m.id}
                            className={cn(
                              "flex items-center justify-between w-full px-2 py-1.5 text-sm rounded hover:bg-accent/50",
                              m.id === model && "bg-accent"
                            )}
                            onClick={() => { setModel(m.id); setModelOpen(false); }}
                          >
                            <span>{m.label}</span>
                            <span className="text-xs text-muted-foreground font-mono">{m.id}</span>
                          </button>
                        ))}
                      </PopoverContent>
                    </Popover>
                  </div>
                </div>
              )}

              {adapterType === "process" && (
                <div className="space-y-3">
                  <div>
                    <label className="text-xs text-muted-foreground mb-1 block">
                      Command
                    </label>
                    <input
                      className="w-full rounded-md border border-border bg-transparent px-3 py-2 text-sm font-mono outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50"
                      placeholder="e.g. node, python"
                      value={command}
                      onChange={(e) => setCommand(e.target.value)}
                    />
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground mb-1 block">
                      Args (comma-separated)
                    </label>
                    <input
                      className="w-full rounded-md border border-border bg-transparent px-3 py-2 text-sm font-mono outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50"
                      placeholder="e.g. script.js, --flag"
                      value={args}
                      onChange={(e) => setArgs(e.target.value)}
                    />
                  </div>
                </div>
              )}

              {adapterType === "http" && (
                <div>
                  <label className="text-xs text-muted-foreground mb-1 block">
                    Webhook URL
                  </label>
                  <input
                    className="w-full rounded-md border border-border bg-transparent px-3 py-2 text-sm font-mono outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50"
                    placeholder="https://..."
                    value={url}
                    onChange={(e) => setUrl(e.target.value)}
                  />
                </div>
              )}
            </div>
          )}

          {step === 3 && (
            <div className="p-4 space-y-4">
              <div className="flex items-center gap-3 mb-2">
                <div className="bg-muted/50 p-2">
                  <ListTodo className="h-5 w-5 text-muted-foreground" />
                </div>
                <div>
                  <h3 className="font-medium">Give it something to do</h3>
                  <p className="text-xs text-muted-foreground">
                    Give your agent a small task to start with — a bug fix, a
                    research question, writing a script.
                  </p>
                </div>
              </div>
              <div>
                <label className="text-xs text-muted-foreground mb-1 block">
                  Task title
                </label>
                <input
                  className="w-full rounded-md border border-border bg-transparent px-3 py-2 text-sm outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50"
                  placeholder="e.g. Research competitor pricing"
                  value={taskTitle}
                  onChange={(e) => setTaskTitle(e.target.value)}
                  autoFocus
                />
              </div>
              <div>
                <label className="text-xs text-muted-foreground mb-1 block">
                  Description (optional)
                </label>
                <textarea
                  className="w-full rounded-md border border-border bg-transparent px-3 py-2 text-sm outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50 resize-none min-h-[80px]"
                  placeholder="Add more detail about what the agent should do..."
                  value={taskDescription}
                  onChange={(e) => setTaskDescription(e.target.value)}
                />
              </div>
            </div>
          )}

          {step === 4 && (
            <div className="p-4 space-y-4">
              <div className="flex items-center gap-3 mb-2">
                <div className="bg-muted/50 p-2">
                  <Rocket className="h-5 w-5 text-muted-foreground" />
                </div>
                <div>
                  <h3 className="font-medium">Ready to launch</h3>
                  <p className="text-xs text-muted-foreground">
                    Everything is set up. Launch your agent and watch it work.
                  </p>
                </div>
              </div>
              <div className="border border-border divide-y divide-border">
                <div className="flex items-center gap-3 px-3 py-2.5">
                  <Building2 className="h-4 w-4 text-muted-foreground shrink-0" />
                  <div className="flex-1 min-w-0">
                    <p className="text-sm font-medium truncate">{companyName}</p>
                    <p className="text-xs text-muted-foreground">Company</p>
                  </div>
                  <Check className="h-4 w-4 text-green-500 shrink-0" />
                </div>
                <div className="flex items-center gap-3 px-3 py-2.5">
                  <Bot className="h-4 w-4 text-muted-foreground shrink-0" />
                  <div className="flex-1 min-w-0">
                    <p className="text-sm font-medium truncate">{agentName}</p>
                    <p className="text-xs text-muted-foreground">
                      {adapterType === "claude_local"
                        ? "Claude Code"
                        : adapterType === "process"
                          ? "Shell Command"
                          : "HTTP Webhook"}
                    </p>
                  </div>
                  <Check className="h-4 w-4 text-green-500 shrink-0" />
                </div>
                <div className="flex items-center gap-3 px-3 py-2.5">
                  <ListTodo className="h-4 w-4 text-muted-foreground shrink-0" />
                  <div className="flex-1 min-w-0">
                    <p className="text-sm font-medium truncate">{taskTitle}</p>
                    <p className="text-xs text-muted-foreground">Task</p>
                  </div>
                  <Check className="h-4 w-4 text-green-500 shrink-0" />
                </div>
              </div>
            </div>
          )}
        </div>

        {/* Error */}
        {error && (
          <div className="px-4 pb-2">
            <p className="text-xs text-destructive">{error}</p>
          </div>
        )}

        {/* Footer */}
        <div className="flex items-center justify-between px-4 py-2.5 border-t border-border">
          <div>
            {step > 1 && (
              <Button
                variant="ghost"
                size="sm"
                onClick={() => setStep((step - 1) as Step)}
                disabled={loading}
              >
                <ArrowLeft className="h-3.5 w-3.5 mr-1" />
                Back
              </Button>
            )}
          </div>
          <div className="flex items-center gap-2">
            {step === 1 && (
              <Button
                size="sm"
                disabled={!companyName.trim() || loading}
                onClick={handleStep1Next}
              >
                {loading ? (
                  <Loader2 className="h-3.5 w-3.5 mr-1 animate-spin" />
                ) : (
                  <ArrowRight className="h-3.5 w-3.5 mr-1" />
                )}
                {loading ? "Creating..." : "Next"}
              </Button>
            )}
            {step === 2 && (
              <Button
                size="sm"
                disabled={!agentName.trim() || loading}
                onClick={handleStep2Next}
              >
                {loading ? (
                  <Loader2 className="h-3.5 w-3.5 mr-1 animate-spin" />
                ) : (
                  <ArrowRight className="h-3.5 w-3.5 mr-1" />
                )}
                {loading ? "Creating..." : "Next"}
              </Button>
            )}
            {step === 3 && (
              <Button
                size="sm"
                disabled={!taskTitle.trim() || loading}
                onClick={handleStep3Next}
              >
                {loading ? (
                  <Loader2 className="h-3.5 w-3.5 mr-1 animate-spin" />
                ) : (
                  <ArrowRight className="h-3.5 w-3.5 mr-1" />
                )}
                {loading ? "Creating..." : "Next"}
              </Button>
            )}
            {step === 4 && (
              <Button size="sm" disabled={loading} onClick={handleLaunch}>
                {loading ? (
                  <Loader2 className="h-3.5 w-3.5 mr-1 animate-spin" />
                ) : (
                  <Rocket className="h-3.5 w-3.5 mr-1" />
                )}
                {loading ? "Launching..." : "Launch Agent"}
              </Button>
            )}
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
