import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { format } from "date-fns";
import { useState } from "react";
import { toast } from "sonner";
import { Page, Panel, Stats } from "@/components/page";
import { Scratchpad } from "@/components/scratchpad";
import { Button } from "@/components/ui/button";
import { Input, Select } from "@/components/ui/input";
import { Tag, statusTone } from "@/components/ui/tag";
import { dueKind, followUpDue, formatDay, formatDue, waitingFor } from "@/lib/format";
import { useWorkspace } from "@/lib/store";

export const Route = createFileRoute("/")({ component: TodayPage });

function TodayPage() {
  const navigate = useNavigate();
  const projects = useWorkspace((s) => s.projects);
  const tasks = useWorkspace((s) => s.tasks);
  const notes = useWorkspace((s) => s.notes);
  const reminders = useWorkspace((s) => s.reminders);
  const boards = useWorkspace((s) => s.boards);
  const waiting = useWorkspace((s) => s.waiting);
  const nudgeWaiting = useWorkspace((s) => s.nudgeWaiting);
  const toggleWaiting = useWorkspace((s) => s.toggleWaiting);
  const focusTaskId = useWorkspace((s) => s.focusTaskId);
  const addTask = useWorkspace((s) => s.addTask);
  const toggleReminder = useWorkspace((s) => s.toggleReminder);
  const setTaskStatus = useWorkspace((s) => s.setTaskStatus);

  const [capture, setCapture] = useState("");
  const [projectId, setProjectId] = useState("");

  const openTasks = tasks.filter((t) => t.status !== "done");
  const overdue = reminders.filter((r) => !r.done && dueKind(r.dueAt) === "overdue");
  const todayRem = reminders.filter((r) => !r.done && dueKind(r.dueAt) === "today");
  const soon = reminders.filter((r) => !r.done && dueKind(r.dueAt) === "soon");
  const focus = tasks.find((t) => t.id === focusTaskId) ?? openTasks.find((t) => t.status === "doing");
  const dueTasks = openTasks.filter((t) => dueKind(t.dueAt) === "today" || dueKind(t.dueAt) === "overdue");
  const recentNotes = [...notes].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)).slice(0, 4);
  const activeProjects = projects.filter((p) => p.status === "active");
  const openWaiting = waiting.filter((w) => !w.done);
  const chase = openWaiting
    .filter(followUpDue)
    .sort((a, b) => (a.followUpAt ?? "").localeCompare(b.followUpAt ?? ""));

  const post = () => {
    if (!capture.trim()) return;
    addTask({ title: capture, projectId: projectId || null });
    setCapture("");
    toast("Task posted to the book");
  };

  return (
    <Page
      wide
      eyebrow="Today"
      title={format(new Date(), "EEEE d MMMM yyyy")}
      description="What is due, what is in focus, and what still needs a home — one posting line to capture work."
    >
      <div className="grid xl:grid-cols-[minmax(0,1fr)_320px] gap-4 items-start">
        {/* Container, so the panels inside size to this column rather than the viewport. */}
        <div className="@container min-w-0 order-2 xl:order-1">
          <Stats
            items={[
              { label: "Open tasks", value: openTasks.length, sub: `${tasks.filter((t) => t.status === "doing").length} in progress`, swatch: "var(--color-accent)" },
              { label: "Overdue", value: overdue.length, sub: "reminders past due", swatch: "var(--color-error)" },
              { label: "Notes", value: notes.length, sub: "pages in the book", swatch: "var(--color-ok)" },
              { label: "Active projects", value: activeProjects.length, sub: `${boards.length} boards & flows`, swatch: "var(--color-warn)" },
            ]}
          />

          <Panel title="Post a line" className="mb-4">
            <form
              className="flex flex-col md:flex-row gap-2"
              onSubmit={(e) => {
                e.preventDefault();
                post();
              }}
            >
              <Input
                value={capture}
                onChange={(e) => setCapture(e.target.value)}
                placeholder="Write a task and press return"
                className="flex-1"
              />
              <Select value={projectId} onChange={(e) => setProjectId(e.target.value)} className="md:w-48">
                <option value="">Unfiled</option>
                {activeProjects.map((p) => (
                  <option key={p.id} value={p.id}>
                    {p.name}
                  </option>
                ))}
              </Select>
              <Button variant="primary" type="submit" disabled={!capture.trim()}>
                Post
              </Button>
            </form>
          </Panel>

          <div className="grid @3xl:grid-cols-2 gap-4">
            <Panel title="Agenda" meta={`${overdue.length + todayRem.length + soon.length} open`}>
              <AgendaGroup
                label="Overdue"
                items={overdue.map((r) => ({
                  id: r.id,
                  title: r.title,
                  meta: formatDue(r.dueAt),
                  to: (r.taskId ? "/tasks" : "/reminders") as "/tasks" | "/reminders",
                  search: r.taskId ? { focus: r.taskId } : undefined,
                  onToggle: () => toggleReminder(r.id),
                }))}
              />
              <AgendaGroup
                label="Today"
                items={[
                  ...todayRem.map((r) => ({
                    id: r.id,
                    title: r.title,
                    meta: formatDue(r.dueAt),
                    to: (r.taskId ? "/tasks" : "/reminders") as "/tasks" | "/reminders",
                    search: r.taskId ? { focus: r.taskId } : undefined,
                    onToggle: () => toggleReminder(r.id),
                  })),
                  ...dueTasks
                    .filter((t) => !todayRem.some((r) => r.taskId === t.id) && !overdue.some((r) => r.taskId === t.id))
                    .map((t) => ({
                      id: t.id,
                      title: t.title,
                      meta: formatDue(t.dueAt),
                      to: "/tasks" as const,
                      search: { focus: t.id },
                      onToggle: () => setTaskStatus(t.id, "done"),
                    })),
                ]}
              />
              <AgendaGroup
                label="Soon"
                items={soon.map((r) => ({
                  id: r.id,
                  title: r.title,
                  meta: formatDue(r.dueAt),
                  to: (r.taskId ? "/tasks" : "/reminders") as "/tasks" | "/reminders",
                  search: r.taskId ? { focus: r.taskId } : undefined,
                  onToggle: () => toggleReminder(r.id),
                }))}
              />
            </Panel>

            <div className="flex flex-col gap-4">
              {openWaiting.length > 0 ? (
                <Panel
                  title="Waiting on"
                  meta={
                    <Link to="/waiting" className="hover:no-underline">
                      {chase.length > 0 ? (
                        <span className="text-error">{chase.length} to follow up</span>
                      ) : (
                        `${openWaiting.length} open`
                      )}
                    </Link>
                  }
                >
                  {chase.length === 0 ? (
                    <p className="text-[13px] text-ink-2">
                      Nothing needs chasing today.{" "}
                      <Link to="/waiting">See all {openWaiting.length}</Link>
                    </p>
                  ) : (
                    <ul className="flex flex-col gap-1">
                      {chase.slice(0, 5).map((w) => (
                        <li key={w.id} className="flex items-center gap-2 min-h-9">
                          <button
                            type="button"
                            aria-label="Mark received"
                            title="Received"
                            className="size-4 rounded-full border border-line-strong shrink-0 hover:border-ok"
                            onClick={() => toggleWaiting(w.id)}
                          />
                          <Link to="/waiting" className="flex-1 min-w-0 hover:no-underline">
                            <span className="block text-[13px] text-ink truncate">{w.title}</span>
                            <span className="block text-[11px] text-ink-3 truncate">
                              {w.who ? `${w.who} · ` : ""}waiting {waitingFor(w.since)}
                              {dueKind(w.followUpAt) === "overdue" ? ` · due ${formatDay(w.followUpAt)}` : ""}
                            </span>
                          </Link>
                          <Button size="sm" onClick={() => nudgeWaiting(w.id)}>
                            Followed up
                          </Button>
                        </li>
                      ))}
                      {chase.length > 5 ? (
                        <li className="text-[12px]">
                          <Link to="/waiting">{chase.length - 5} more</Link>
                        </li>
                      ) : null}
                    </ul>
                  )}
                </Panel>
              ) : null}
              <Panel title="Focus">
                {focus ? (
                  <div>
                    <Link
                      to="/tasks"
                      search={{ focus: focus.id }}
                      className="text-[16px] font-semibold text-ink hover:no-underline"
                    >
                      {focus.title}
                    </Link>
                    <div className="mt-2 flex flex-wrap gap-1.5">
                      <Tag tone={statusTone(focus.status)}>{focus.status}</Tag>
                      <Tag tone={statusTone(focus.priority)}>{focus.priority}</Tag>
                      {focus.dueAt ? <Tag>{formatDue(focus.dueAt)}</Tag> : null}
                    </div>
                    {focus.body ? <p className="mt-2 text-[13px] text-ink-2 line-clamp-4">{focus.body}</p> : null}
                    <div className="mt-3 flex gap-2">
                      <Button size="sm" onClick={() => setTaskStatus(focus.id, "doing")}>
                        Mark doing
                      </Button>
                      <Button size="sm" variant="primary" onClick={() => setTaskStatus(focus.id, "done")}>
                        Mark done
                      </Button>
                    </div>
                  </div>
                ) : (
                  <p className="text-[13px] text-ink-2">No focus task. Open the book and pick one.</p>
                )}
              </Panel>
              <Panel title="Recent notes">
                <ul className="divide-y divide-line-hair -mx-3.5">
                  {recentNotes.map((n) => (
                    <li key={n.id}>
                      <Link
                        to="/notes/$noteId"
                        params={{ noteId: n.id }}
                        className="flex items-center justify-between gap-3 px-3.5 py-2 text-ink hover:bg-sunken hover:no-underline"
                      >
                        <span className="truncate text-[13px] font-medium">{n.title}</span>
                        <span className="text-[12px] text-ink-3 shrink-0">
                          {projects.find((p) => p.id === n.projectId)?.name ?? "Unfiled"}
                        </span>
                      </Link>
                    </li>
                  ))}
                </ul>
              </Panel>
            </div>
          </div>

          <div className="mt-4 grid @md:grid-cols-2 @3xl:grid-cols-3 gap-3">
            {activeProjects.map((p) => {
              const pt = tasks.filter((t) => t.projectId === p.id);
              const done = pt.filter((t) => t.status === "done").length;
              const pct = pt.length ? Math.round((done / pt.length) * 100) : 0;
              return (
                <Link
                  key={p.id}
                  to="/projects/$projectId"
                  params={{ projectId: p.id }}
                  className="border border-line rounded-md p-3.5 bg-surface text-ink hover:no-underline hover:shadow-[var(--shadow-pop)]"
                >
                  <div className="flex items-center justify-between gap-2">
                    <strong className="text-[14px]">{p.name}</strong>
                    <span className="font-mono text-[12px] tabular-nums text-ink-2">{pct}%</span>
                  </div>
                  <div className="mt-2 h-1.5 rounded-full bg-neutral overflow-hidden">
                    <i className="block h-full bg-ok-emphasis rounded-full" style={{ width: `${pct}%` }} />
                  </div>
                  <p className="mt-2 text-[12px] text-ink-2">
                    {pt.length} tasks · {notes.filter((n) => n.projectId === p.id).length} notes
                  </p>
                </Link>
              );
            })}
            <button
              type="button"
              className="border border-dashed border-line rounded-md p-3.5 text-left text-[13px] text-ink-2 hover:bg-sunken"
              onClick={() => void navigate({ to: "/projects" })}
            >
              Open projects →
            </button>
          </div>
        </div>
        {/* First on small screens: a jot pad you have to scroll to is one you won't use. */}
        <Scratchpad className="order-1 xl:order-2 xl:sticky xl:top-[76px] xl:max-h-[calc(100dvh-92px)]" />
      </div>
    </Page>
  );
}

function AgendaGroup({
  label,
  items,
}: {
  label: string;
  items: {
    id: string;
    title: string;
    meta: string;
    to: "/tasks" | "/reminders";
    search?: { focus: string };
    onToggle: () => void;
  }[];
}) {
  if (!items.length) return null;
  return (
    <div className="mb-3 last:mb-0">
      <div className="text-[12px] font-semibold text-ink-2 mb-1">{label}</div>
      <ul className="flex flex-col gap-1">
        {items.map((item) => (
          <li key={item.id} className="flex items-center gap-2 min-h-9">
            <button
              type="button"
              aria-label="Mark done"
              className="size-4 rounded-full border border-line-strong shrink-0 hover:border-ok"
              onClick={item.onToggle}
            />
            {item.to === "/tasks" ? (
              <Link
                to="/tasks"
                search={item.search}
                className="flex-1 min-w-0 text-[13px] text-ink truncate hover:no-underline"
              >
                {item.title}
              </Link>
            ) : (
              <Link to="/reminders" className="flex-1 min-w-0 text-[13px] text-ink truncate hover:no-underline">
                {item.title}
              </Link>
            )}
            <span className="font-mono text-[11px] tabular-nums text-ink-3 shrink-0">{item.meta}</span>
          </li>
        ))}
      </ul>
    </div>
  );
}
