"use client";

import { useState } from "react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Select } from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import type {
  FleetAgent,
  TaskEvent,
  TaskPriority,
  TaskRecord,
  TaskStatus,
  TaskTemplate,
} from "@/lib/types";

const COLUMNS: TaskStatus[] = ["Backlog", "Todo", "In Progress", "Review", "Done"];
const PRIORITIES: TaskPriority[] = ["Low", "Medium", "High", "Critical"];

function familyVariant(family: string | null) {
  return family === "zeroclaw" ? "success" : "default";
}

function dispatchVariant(state: TaskRecord["dispatch_state"]) {
  return state === "failed" ? "warning" : state === "completed" ? "success" : "secondary";
}

export function TasksClient({
  initialTasks,
  initialEvents,
  agents,
  templates,
}: {
  initialTasks: TaskRecord[];
  initialEvents: TaskEvent[];
  agents: FleetAgent[];
  templates: TaskTemplate[];
}) {
  const [tasks, setTasks] = useState(initialTasks);
  const [events, setEvents] = useState(initialEvents);
  const [formState, setFormState] = useState({
    templateKey: "",
    title: "",
    description: "",
    assignee: "",
    priority: "Medium" as TaskPriority,
    tags: "",
    repoSlug: "",
    baseBranch: "main",
    preferredAgent: "codex",
    reasoningEffort: "high",
    modelHint: "",
  });

  const selectedTemplate = templates.find((template) => template.key === formState.templateKey) || null;
  const selectedAgent = agents.find((agent) => agent.assignmentKey === formState.assignee) || null;
  const failedTasks = tasks.filter((task) => task.dispatch_state === "failed");

  async function refreshData() {
    const [taskResponse, eventResponse] = await Promise.all([
      fetch("/api/tasks"),
      fetch("/api/dispatch-history"),
    ]);
    setTasks((await taskResponse.json()) as TaskRecord[]);
    setEvents((await eventResponse.json()) as TaskEvent[]);
  }

  function applyTemplate(templateKey: string) {
    const template = templates.find((entry) => entry.key === templateKey) || null;
    if (!template) {
      setFormState((current) => ({ ...current, templateKey }));
      return;
    }

    setFormState((current) => ({
      ...current,
      templateKey,
      title: current.title || template.title,
      priority: template.defaults.priority,
      tags: template.tags.join(", "),
      repoSlug: template.defaults.repoSlug || current.repoSlug,
      baseBranch: template.defaults.baseBranch || current.baseBranch,
      preferredAgent: template.defaults.preferredAgent || current.preferredAgent,
      reasoningEffort: template.defaults.reasoningEffort || current.reasoningEffort,
    }));
  }

  async function createTask(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const tags = formState.tags
      .split(",")
      .map((tag) => tag.trim())
      .filter(Boolean);

    await fetch("/api/tasks", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        title: formState.title,
        description: formState.description,
        assignee: formState.assignee,
        priority: formState.priority,
        tags,
        template_key: formState.templateKey || null,
        repo_slug: formState.repoSlug || null,
        base_branch: formState.baseBranch || null,
        preferred_agent: formState.preferredAgent || null,
        reasoning_effort: formState.reasoningEffort || null,
        model_hint: formState.modelHint || null,
        family: selectedAgent?.family || selectedTemplate?.family || null,
        target_host: selectedAgent?.host || selectedTemplate?.defaults.targetHost || "",
        target_channel: selectedAgent?.channels[0]?.value || selectedTemplate?.defaults.targetChannel || "",
        dispatch_method: selectedAgent?.defaultDispatchMethod || selectedTemplate?.defaults.dispatchMethod || "manual",
      }),
    });

    setFormState({
      templateKey: "",
      title: "",
      description: "",
      assignee: "",
      priority: "Medium",
      tags: "",
      repoSlug: "",
      baseBranch: "main",
      preferredAgent: "codex",
      reasoningEffort: "high",
      modelHint: "",
    });
    await refreshData();
  }

  async function patchTask(taskId: number, payload: Partial<TaskRecord>) {
    await fetch(`/api/tasks/${taskId}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    await refreshData();
  }

  async function dispatchTask(taskId: number) {
    await fetch(`/api/tasks/${taskId}/dispatch`, { method: "POST" });
    await refreshData();
  }

  async function acknowledgeTask(taskId: number) {
    await fetch(`/api/tasks/${taskId}/ack`, { method: "POST" });
    await refreshData();
  }

  return (
    <div className="space-y-6">
      <div className="grid gap-4 xl:grid-cols-[minmax(0,1.2fr)_360px]">
        <Card>
          <CardHeader>
            <CardTitle>Unified Task Intake</CardTitle>
            <CardDescription>
              Create typed tasks, apply dispatch templates, and route work to OpenClaw or ZeroClaw.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <form className="grid gap-3 md:grid-cols-2" onSubmit={createTask}>
              <Select value={formState.templateKey} onChange={(event) => applyTemplate(event.target.value)}>
                <option value="">Select template</option>
                {templates.map((template) => (
                  <option key={template.key} value={template.key}>
                    {template.title} • {template.family}
                  </option>
                ))}
              </Select>
              <Select
                value={formState.assignee}
                onChange={(event) => setFormState((current) => ({ ...current, assignee: event.target.value }))}
              >
                <option value="">Select agent</option>
                {agents.map((agent) => (
                  <option key={agent.slug} value={agent.assignmentKey}>
                    {agent.name} • {agent.family} • {agent.host}
                  </option>
                ))}
              </Select>
              <Input
                placeholder="Task title"
                required
                value={formState.title}
                onChange={(event) => setFormState((current) => ({ ...current, title: event.target.value }))}
              />
              <Select
                value={formState.priority}
                onChange={(event) =>
                  setFormState((current) => ({ ...current, priority: event.target.value as TaskPriority }))
                }
              >
                {PRIORITIES.map((priority) => (
                  <option key={priority} value={priority}>
                    {priority}
                  </option>
                ))}
              </Select>
              <Input
                placeholder="Repo slug from repo-map.json (for example TopherMayor/openclaw-taskboard)"
                value={formState.repoSlug}
                onChange={(event) => setFormState((current) => ({ ...current, repoSlug: event.target.value }))}
              />
              <Input
                placeholder="Base branch"
                value={formState.baseBranch}
                onChange={(event) => setFormState((current) => ({ ...current, baseBranch: event.target.value }))}
              />
              <Input
                placeholder="Preferred swarm agent"
                value={formState.preferredAgent}
                onChange={(event) => setFormState((current) => ({ ...current, preferredAgent: event.target.value }))}
              />
              <Input
                placeholder="Reasoning effort"
                value={formState.reasoningEffort}
                onChange={(event) => setFormState((current) => ({ ...current, reasoningEffort: event.target.value }))}
              />
              <Input
                className="md:col-span-2"
                placeholder="Tags (comma-separated)"
                value={formState.tags}
                onChange={(event) => setFormState((current) => ({ ...current, tags: event.target.value }))}
              />
              <Input
                className="md:col-span-2"
                placeholder="Model hint (optional)"
                value={formState.modelHint}
                onChange={(event) => setFormState((current) => ({ ...current, modelHint: event.target.value }))}
              />
              <div className="md:col-span-2">
                <Textarea
                  placeholder="Describe the task, target host, expected outcome, and any validation steps."
                  value={formState.description}
                  onChange={(event) => setFormState((current) => ({ ...current, description: event.target.value }))}
                />
              </div>
              <div className="md:col-span-2 flex items-center justify-between gap-3">
                <p className="text-sm text-slate-400">
                  {selectedAgent
                    ? `Dispatch target: ${selectedAgent.family} on ${selectedAgent.host}`
                    : selectedTemplate
                      ? `Template dispatch: ${selectedTemplate.defaults.dispatchMethod}`
                      : "Select an agent or template to prefill dispatch metadata."}
                </p>
                <Button type="submit">Create Task</Button>
              </div>
            </form>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Failure Queue</CardTitle>
            <CardDescription>
              Failed dispatches stay visible until retried or completed manually.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-3">
            {failedTasks.length === 0 ? (
              <p className="text-sm text-slate-400">No failed dispatches.</p>
            ) : (
              failedTasks.map((task) => (
                <div className="rounded-xl border border-amber-400/20 bg-amber-400/5 p-4" key={task.id}>
                  <div className="flex flex-wrap items-center justify-between gap-2">
                    <p className="font-medium text-white">{task.title}</p>
                    <Badge variant="warning">{task.dispatch_state}</Badge>
                  </div>
                  <p className="mt-2 text-sm text-slate-300">{task.last_error || "No error text captured."}</p>
                  <Button className="mt-3 w-full" size="sm" variant="outline" onClick={() => dispatchTask(task.id)}>
                    Retry Dispatch
                  </Button>
                </div>
              ))
            )}
          </CardContent>
        </Card>
      </div>

      <Card>
        <CardHeader>
          <CardTitle>Recent Dispatch Activity</CardTitle>
          <CardDescription>
            Latest control-plane events across both families.
          </CardDescription>
        </CardHeader>
        <CardContent className="grid gap-3 lg:grid-cols-3">
          {events.slice(0, 6).map((event) => (
            <div className="rounded-xl border border-white/10 bg-slate-950/40 p-4" key={event.id}>
              <div className="flex flex-wrap gap-2">
                <Badge variant={familyVariant(event.family)}>{event.family || "manual"}</Badge>
                <Badge variant={event.event_type === "dispatch_failed" ? "warning" : "secondary"}>
                  {event.event_type}
                </Badge>
              </div>
              <p className="mt-3 font-medium text-white">{event.summary}</p>
              <p className="mt-2 text-sm text-slate-300">{event.detail || "No detail captured."}</p>
              <p className="mt-2 text-xs uppercase tracking-[0.2em] text-slate-500">{event.created_at}</p>
            </div>
          ))}
        </CardContent>
      </Card>

      <div className="grid gap-4 xl:grid-cols-5">
        {COLUMNS.map((column) => {
          const columnTasks = tasks.filter((task) => task.status === column);
          return (
            <Card className="min-h-[420px]" key={column}>
              <CardHeader className="pb-4">
                <CardTitle className="flex items-center justify-between text-base">
                  <span>{column}</span>
                  <Badge variant="secondary">{columnTasks.length}</Badge>
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-3">
                {columnTasks.map((task) => (
                  <div className="rounded-xl border border-white/10 bg-slate-950/40 p-4" key={task.id}>
                    <div className="flex items-start justify-between gap-3">
                      <h3 className="font-medium text-white">{task.title}</h3>
                      <Badge variant={task.priority === "Critical" ? "warning" : "outline"}>
                        {task.priority}
                      </Badge>
                    </div>
                    <p className="mt-2 text-sm text-slate-300">{task.description || "No description"}</p>
                    <div className="mt-3 flex flex-wrap gap-2 text-xs text-slate-400">
                      <Badge variant={familyVariant(task.family)}>{task.family || "manual"}</Badge>
                      <Badge variant="secondary">{task.assignee || "Unassigned"}</Badge>
                      <Badge variant={dispatchVariant(task.dispatch_state)}>{task.dispatch_state}</Badge>
                      {task.tags.map((tag) => (
                        <Badge key={tag} variant="outline">
                          {tag}
                        </Badge>
                      ))}
                    </div>
                    <dl className="mt-3 grid gap-1 text-xs text-slate-400">
                      <div className="flex justify-between gap-2">
                        <dt>Host</dt>
                        <dd>{task.target_host || "n/a"}</dd>
                      </div>
                      <div className="flex justify-between gap-2">
                        <dt>Channel</dt>
                        <dd className="text-right">{task.target_channel || "n/a"}</dd>
                      </div>
                    </dl>
                    <div className="mt-4 space-y-2">
                      {task.dispatch_state !== "dispatched" && task.dispatch_state !== "completed" ? (
                        <Button className="w-full" size="sm" onClick={() => dispatchTask(task.id)}>
                          Dispatch
                        </Button>
                      ) : null}
                      {task.dispatch_state === "dispatched" ? (
                        <Button className="w-full" size="sm" variant="outline" onClick={() => acknowledgeTask(task.id)}>
                          Mark Acknowledged
                        </Button>
                      ) : null}
                      {task.status !== "Done" ? (
                        <Button className="w-full" size="sm" variant="outline" onClick={() => patchTask(task.id, { status: "Done" })}>
                          Mark Done
                        </Button>
                      ) : null}
                    </div>
                  </div>
                ))}
              </CardContent>
            </Card>
          );
        })}
      </div>
    </div>
  );
}
