"use client";

import Link from "next/link";
import { ChevronDown, ChevronRight, ExternalLink, Pencil, Plus } from "lucide-react";
import { useMemo, useState, useTransition } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import type { ListIndexItem, ListWithItemsDto } from "../server/queries";
import { addItem, createList, toggleItem, updateListProperties } from "../server/actions";

export function ListsIndex({ lists }: { lists: ListWithItemsDto[] }) {
  const [listRows, setListRows] = useState(lists);
  const [type, setType] = useState("shopping");
  const [name, setName] = useState("");
  const [, startTransition] = useTransition();

  const grouped = useMemo(() => {
    const groups = new Map<string, ListWithItemsDto[]>();
    for (const list of listRows) {
      groups.set(list.type, [...(groups.get(list.type) ?? []), list]);
    }
    return [...groups.entries()].sort(([a], [b]) => a.localeCompare(b));
  }, [listRows]);

  function addList() {
    startTransition(async () => {
      const created = await createList({ type, name });
      setListRows((current) => [
        ...current,
        {
          id: created.id,
          type: created.type,
          name: created.name,
          archived: created.archived,
          openCount: 0,
          doneCount: 0,
          createdAt: created.createdAt.toISOString(),
          items: [],
        },
      ]);
      setName("");
    });
  }

  function handleToggle(listId: string, item: ListIndexItem, done: boolean) {
    setListRows((current) =>
      current.map((list) =>
        list.id !== listId
          ? list
          : {
              ...list,
              openCount: list.openCount + (done ? -1 : 1),
              doneCount: list.doneCount + (done ? 1 : -1),
              items: list.items.map((i) => (i.id === item.id ? { ...i, done } : i)),
            },
      ),
    );
    startTransition(async () => {
      await toggleItem({ id: item.id, done });
    });
  }

  function handleAddItem(listId: string, text: string) {
    setListRows((current) =>
      current.map((list) =>
        list.id !== listId
          ? list
          : {
              ...list,
              openCount: list.openCount + 1,
              items: [
                ...list.items,
                {
                  id: `temp-${Date.now()}`,
                  text,
                  done: false,
                  position: list.items.length,
                },
              ],
            },
      ),
    );

    startTransition(async () => {
      await addItem({ listId, text });
      const { listListsWithItems } = await import("../server/queries");
      const refreshed = await listListsWithItems();
      setListRows(refreshed);
    });
  }

  function handleUpdateList(listId: string, patch: { name?: string; type?: string }) {
    setListRows((current) =>
      current.map((list) => (list.id === listId ? { ...list, ...patch } : list)),
    );
    startTransition(async () => {
      await updateListProperties({ id: listId, ...patch });
    });
  }

  return (
    <div className="mx-auto grid w-full max-w-5xl gap-6">
      <div className="flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
        <div>
          <h2 className="serif text-[22px] tracking-tight">Lists</h2>
          <p className="muted text-[13px] mt-1">Shopping, tasks, and whatever comes next.</p>
        </div>
        <div
          className="grid gap-2 rounded-[var(--r-md)] border-[0.5px] bg-[var(--card)] p-3 sm:grid-cols-[140px_220px_auto]"
          style={{ borderColor: "var(--hair)" }}
        >
          <div className="space-y-1">
            <Label htmlFor="new-list-type">Type</Label>
            <Input
              id="new-list-type"
              value={type}
              onChange={(event) => setType(event.target.value)}
            />
          </div>
          <div className="space-y-1">
            <Label htmlFor="new-list-name">Name</Label>
            <Input
              id="new-list-name"
              value={name}
              onChange={(event) => setName(event.target.value)}
            />
          </div>
          <Button className="self-end" onClick={addList} disabled={!type || !name}>
            <Plus className="size-3.5" />
            New list
          </Button>
        </div>
      </div>

      <div className="grid gap-6">
        {grouped.map(([groupType, groupLists]) => (
          <section key={groupType} className="grid gap-3">
            <div className="eyebrow">{groupType}</div>
            <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
              {groupLists.map((list) => (
                <ListCard
                  key={list.id}
                  list={list}
                  onToggle={handleToggle}
                  onAddItem={handleAddItem}
                  onUpdateList={handleUpdateList}
                />
              ))}
            </div>
          </section>
        ))}
      </div>
    </div>
  );
}

function ListCard({
  list,
  onToggle,
  onAddItem,
  onUpdateList,
}: {
  list: ListWithItemsDto;
  onToggle: (listId: string, item: ListIndexItem, done: boolean) => void;
  onAddItem: (listId: string, text: string) => void;
  onUpdateList: (listId: string, patch: { name?: string; type?: string }) => void;
}) {
  const [expanded, setExpanded] = useState(true);
  const [editing, setEditing] = useState(false);
  const [draftName, setDraftName] = useState(list.name);
  const [draftType, setDraftType] = useState(list.type);
  const [itemDraft, setItemDraft] = useState("");

  function saveListProperties() {
    const name = draftName.trim();
    const type = draftType.trim();
    if (!name || !type) return;
    onUpdateList(list.id, { name, type });
    setEditing(false);
  }

  function submitItem() {
    const text = itemDraft.trim();
    if (!text) return;
    onAddItem(list.id, text);
    setItemDraft("");
  }

  return (
    <div
      className="rounded-[var(--r-lg)] border-[0.5px] bg-[var(--card)] text-[var(--ink)] shadow-[var(--shadow-1)]"
      style={{ borderColor: "var(--hair)" }}
    >
      <div className="card-h">
        <div className="flex items-center gap-2 min-w-0">
          <button
            type="button"
            onClick={() => setExpanded((v) => !v)}
            className="text-[var(--ink-mute)] hover:text-[var(--ink)] transition-colors"
            aria-label={expanded ? "Collapse" : "Expand"}
          >
            {expanded ? <ChevronDown className="size-4" /> : <ChevronRight className="size-4" />}
          </button>
          <div className="min-w-0 flex-1">
            {editing ? (
              <div className="grid gap-2">
                <Input value={draftName} onChange={(e) => setDraftName(e.target.value)} />
                <Input value={draftType} onChange={(e) => setDraftType(e.target.value)} />
                <div className="flex gap-2">
                  <Button type="button" size="sm" onClick={saveListProperties}>
                    Save
                  </Button>
                  <Button
                    type="button"
                    size="sm"
                    variant="ghost"
                    onClick={() => {
                      setDraftName(list.name);
                      setDraftType(list.type);
                      setEditing(false);
                    }}
                  >
                    Cancel
                  </Button>
                </div>
              </div>
            ) : (
              <>
                <h3 className="serif text-[15px] truncate text-[var(--ink)] m-0 font-medium">
                  {list.name}
                </h3>
                <div className="meta">
                  {list.type} · {list.openCount} open · {list.doneCount} done
                </div>
              </>
            )}
          </div>
        </div>
        <div className="flex shrink-0 items-center gap-1">
          {!editing && (
            <button
              type="button"
              onClick={() => setEditing(true)}
              className="text-[var(--ink-mute)] hover:text-[var(--ink)] transition-colors"
              aria-label={`Edit ${list.name}`}
            >
              <Pencil className="size-4" />
            </button>
          )}
          <Link
            href={`/lists/${list.id}`}
            className="text-[var(--ink-mute)] hover:text-[var(--ink)] transition-colors"
            aria-label={`Open ${list.name}`}
          >
            <ExternalLink className="size-4" />
          </Link>
        </div>
      </div>

      {expanded && (
        <div>
          {list.items.length === 0 ? (
            <p className="muted px-[14px] py-3 text-[13px]">
              {list.openCount === 0 ? "All done!" : "No items to show."}
            </p>
          ) : (
            <div>
              {list.items.map((item) => (
                <div
                  key={item.id}
                  className={`list-row ${item.done ? "checked" : ""}`}
                  style={{ padding: "8px 14px" }}
                >
                  <button
                    type="button"
                    aria-label={`Complete ${item.text}`}
                    aria-pressed={item.done}
                    className={`checkbox ${item.done ? "on" : ""}`}
                    onClick={() => onToggle(list.id, item, !item.done)}
                  >
                    {item.done && (
                      <svg
                        width="12"
                        height="12"
                        viewBox="0 0 24 24"
                        fill="none"
                        stroke="white"
                        strokeWidth="2.4"
                        strokeLinecap="round"
                        strokeLinejoin="round"
                      >
                        <path d="M5 12l5 5L20 7" />
                      </svg>
                    )}
                  </button>
                  <span className="row-text flex-1 text-[13.5px] truncate">{item.text}</span>
                </div>
              ))}
              {list.openCount > list.items.filter((i) => !i.done).length && (
                <div className="px-[14px] py-2">
                  <Link
                    href={`/lists/${list.id}`}
                    className="text-[12px] text-[var(--ink-mute)] hover:text-[var(--ink)] transition-colors"
                  >
                    +{list.openCount - list.items.filter((i) => !i.done).length} more — open list
                  </Link>
                </div>
              )}
            </div>
          )}

          <div className="flex gap-2 px-[14px] py-3 border-t border-[var(--hair)]">
            <Input
              value={itemDraft}
              onChange={(e) => setItemDraft(e.target.value)}
              placeholder="Add a task…"
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  e.preventDefault();
                  submitItem();
                }
              }}
            />
            <Button type="button" size="sm" disabled={!itemDraft.trim()} onClick={submitItem}>
              Add
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
