"use client";

import { useSyncExternalStore } from "react";
import { Check } from "@/components/ui/Icons";
import { cn } from "@/lib/cn";

interface ChecklistBlockProps {
  storageKey: string;
  title?: string;
  items: { label: string; detail?: string }[];
}

const listeners = new Set<() => void>();

function readChecked(key: string): string {
  try {
    return window.localStorage.getItem(key) ?? "";
  } catch {
    return "";
  }
}

function subscribe(callback: () => void) {
  listeners.add(callback);
  window.addEventListener("storage", callback);
  return () => {
    listeners.delete(callback);
    window.removeEventListener("storage", callback);
  };
}

/** A working checklist. Ticks are remembered in this browser only; nothing is sent anywhere. */
export function ChecklistBlock({ storageKey, title, items }: ChecklistBlockProps) {
  const raw = useSyncExternalStore(subscribe, () => readChecked(storageKey), () => "");
  const checked = new Set(raw ? raw.split(",").map(Number) : []);

  const toggle = (index: number) => {
    const next = new Set(checked);
    if (next.has(index)) next.delete(index);
    else next.add(index);
    try {
      window.localStorage.setItem(storageKey, [...next].join(","));
    } catch {
      // Storage unavailable: the checklist still renders, it just won't remember ticks.
    }
    listeners.forEach((listener) => listener());
  };

  return (
    <div className="mt-8 overflow-hidden rounded-lg border border-line bg-surface">
      <div className="flex items-center justify-between gap-4 border-b border-line px-5 py-3.5">
        <p className="text-label uppercase text-muted">{title ?? "Checklist"}</p>
        <p className="font-mono text-data text-muted" aria-live="polite">
          {checked.size}/{items.length}
        </p>
      </div>
      <ul>
        {items.map((item, index) => {
          const isChecked = checked.has(index);
          const id = `${storageKey}-${index}`;
          return (
            <li key={item.label} className="border-b border-line last:border-b-0">
              <label htmlFor={id} className="flex cursor-pointer gap-4 px-5 py-4 transition-colors hover:bg-paper">
                <input id={id} type="checkbox" checked={isChecked} onChange={() => toggle(index)} className="peer sr-only" />
                <span
                  aria-hidden="true"
                  className={cn(
                    "mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-sm border transition-colors peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-signal",
                    isChecked ? "border-signal bg-signal text-white" : "border-line-strong bg-paper",
                  )}
                >
                  {isChecked ? <Check size={13} /> : null}
                </span>
                <span>
                  <span className={cn("block font-medium", isChecked && "text-muted line-through decoration-line-strong")}>{item.label}</span>
                  {item.detail ? <span className="mt-1 block text-[0.9375rem] text-ink-soft">{item.detail}</span> : null}
                </span>
              </label>
            </li>
          );
        })}
      </ul>
    </div>
  );
}
