"use client";

import { useMemo } from "react";
import { useParams } from "next/navigation";
import type { inferRouterOutputs } from "@trpc/server";
import { Calendar } from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import { api } from "@/lib/trpc";
import type { AppRouter } from "@/server/root";
import { cn } from "@/lib/utils";

type ListObject = inferRouterOutputs<AppRouter>["objects"]["list"]["objects"][number];

type PlannerTask = ListObject & {
  dueDate?: unknown;
  properties?: unknown;
};

function readDueDateString(task: PlannerTask): string | null {
  if (typeof task.dueDate === "string" && task.dueDate.trim()) {
    return task.dueDate.trim();
  }
  const props = task.properties;
  if (props && typeof props === "object" && props !== null) {
    const v = (props as Record<string, unknown>).dueDate;
    if (typeof v === "string" && v.trim()) return v.trim();
  }
  const content = task.content;
  if (content && typeof content === "object" && content !== null) {
    const v = (content as Record<string, unknown>).dueDate;
    if (typeof v === "string" && v.trim()) return v.trim();
  }
  return null;
}

function toLocalDateKey(iso: string): string | null {
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return null;
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
}

function formatGroupHeading(dateKey: string): string {
  const [y, mo, da] = dateKey.split("-").map(Number);
  const date = new Date(y, mo - 1, da);
  return date.toLocaleDateString(undefined, {
    weekday: "long",
    month: "long",
    day: "numeric",
    year: "numeric",
  });
}

function formatWeekRangeLabel(dateKey: string): string {
  const [y, mo, da] = dateKey.split("-").map(Number);
  const start = new Date(y, mo - 1, da);
  const day = start.getDay();
  const diff = start.getDate() - day + (day === 0 ? -6 : 1);
  const weekStart = new Date(start);
  weekStart.setDate(diff);
  const weekEnd = new Date(weekStart);
  weekEnd.setDate(weekStart.getDate() + 6);
  const opts: Intl.DateTimeFormatOptions = { month: "short", day: "numeric" };
  const a = weekStart.toLocaleDateString(undefined, opts);
  const b = weekEnd.toLocaleDateString(undefined, {
    ...opts,
    year: weekEnd.getFullYear() !== weekStart.getFullYear() ? "numeric" : undefined,
  });
  return `Week of ${a} – ${b}`;
}

const NO_DATE_KEY = "__no_date__";

function statusLabel(status: string | null | undefined): string {
  switch (status) {
    case "in_progress":
      return "In progress";
    case "done":
      return "Done";
    case "closed":
      return "Closed";
    case "open":
    default:
      return "Open";
  }
}

function StatusBadge({ status }: { status: string | null | undefined }) {
  const s = status ?? "open";
  if (s === "in_progress") {
    return (
      <Badge
        className={cn(
          "shrink-0 border-transparent bg-blue-500/15 font-medium text-blue-700",
          "hover:bg-blue-500/20 dark:text-blue-300",
        )}
      >
        {statusLabel(s)}
      </Badge>
    );
  }
  if (s === "done") {
    return (
      <Badge
        className={cn(
          "shrink-0 border-transparent bg-green-500/15 font-medium text-green-700",
          "hover:bg-green-500/20 dark:text-green-300",
        )}
      >
        {statusLabel(s)}
      </Badge>
    );
  }
  return (
    <Badge variant="outline" className="shrink-0 font-medium">
      {statusLabel(s)}
    </Badge>
  );
}

export default function PlannerPage() {
  const params = useParams();

  const workspaceSlug =
    typeof params?.workspaceSlug === "string" ? params.workspaceSlug : undefined;

  const listQuery = api.objects.list.useQuery(
    { workspace: workspaceSlug!, type: "task", limit: 200 },
    { enabled: Boolean(workspaceSlug) },
  );

  const grouped = useMemo(() => {
    const rows = (listQuery.data?.objects ?? []) as PlannerTask[];
    const map = new Map<string, PlannerTask[]>();

    for (const task of rows) {
      const raw = readDueDateString(task);
      const key = raw ? toLocalDateKey(raw) : null;
      const groupKey = key ?? NO_DATE_KEY;
      const list = map.get(groupKey) ?? [];
      list.push(task);
      map.set(groupKey, list);
    }

    const keys = [...map.keys()].sort((a, b) => {
      if (a === NO_DATE_KEY) return 1;
      if (b === NO_DATE_KEY) return -1;
      return a.localeCompare(b);
    });

    for (const k of keys) {
      const list = map.get(k)!;
      list.sort((a, b) => a.title.localeCompare(b.title));
    }

    return { keys, map };
  }, [listQuery.data?.objects]);

  const taskCount = listQuery.data?.objects?.length ?? 0;
  const isEmpty =
    Boolean(workspaceSlug) && !listQuery.isLoading && taskCount === 0;

  if (!workspaceSlug) {
    return (
      <div className="mx-auto max-w-3xl px-8 py-10">
        <p className="text-sm text-muted-foreground">No workspace selected.</p>
      </div>
    );
  }

  return (
    <div className="mx-auto flex h-full max-w-3xl flex-col px-8 py-10">
      <header className="flex flex-wrap items-start gap-4 border-b border-border pb-6">
        <div
          className={cn(
            "flex size-11 shrink-0 items-center justify-center rounded-xl",
            "border border-border bg-muted/40 text-muted-foreground",
          )}
        >
          <Calendar className="size-5" strokeWidth={1.75} />
        </div>
        <div className="min-w-0 flex-1">
          <div className="flex flex-wrap items-center gap-3">
            <h1 className="text-3xl font-bold tracking-tight">Planner</h1>
            <Badge variant="secondary" className="font-normal text-muted-foreground">
              Calendar view coming soon
            </Badge>
          </div>
        </div>
      </header>

      {listQuery.isLoading ? (
        <p className="mt-8 text-sm text-muted-foreground">Loading tasks…</p>
      ) : isEmpty ? (
        <div
          className={cn(
            "mt-8 rounded-lg border border-dashed border-border bg-muted/30",
            "p-12 text-center text-sm text-muted-foreground",
          )}
        >
          No tasks in this workspace yet. Create tasks in a space to see them here.
        </div>
      ) : (
        <ScrollArea className="mt-6 min-h-[min(480px,calc(100vh-14rem))] flex-1 pr-3">
          <div className="space-y-8 pb-6">
            {grouped.keys.map((key) => {
              const tasks = grouped.map.get(key)!;
              const isNoDate = key === NO_DATE_KEY;
              return (
                <section key={key} className="space-y-3">
                  <div>
                    <h2 className="text-sm font-semibold tracking-tight text-foreground">
                      {isNoDate ? "No date" : formatGroupHeading(key)}
                    </h2>
                    {!isNoDate ? (
                      <p className="text-xs text-muted-foreground">
                        {formatWeekRangeLabel(key)}
                      </p>
                    ) : null}
                  </div>
                  <ul
                    className={cn(
                      "divide-y divide-border overflow-hidden rounded-lg border border-border",
                      "bg-card shadow-sm",
                    )}
                  >
                    {tasks.map((task) => (
                      <li
                        key={task.id}
                        className="flex items-center gap-3 px-4 py-3 text-sm"
                      >
                        <span className="min-w-0 flex-1 truncate font-medium">
                          {task.title || "Untitled"}
                        </span>
                        <StatusBadge status={task.status} />
                      </li>
                    ))}
                  </ul>
                </section>
              );
            })}
          </div>
        </ScrollArea>
      )}
    </div>
  );
}
