"use client";

import Link from "next/link";
import { useRef, useState } from "react";
import { ChevronDown, GripVertical, Home, X } from "lucide-react";
import { copyPagesAction, deletePageRowAction, duplicatePageAction, reorderPagesAction, setHomepageAction } from "@/lib/actions/pages";
import { PAGE_STATUSES } from "@/lib/domain/enums";
import { cn } from "@/lib/utils";
import { StatusLine, useRun } from "@/components/features/accounts/use-run";
import { pillClass } from "@/components/features/page-editor/ed-ui";

export interface ManagedPageRow {
  id: string;
  title: string;
  slug: string;
  status: string;
  updatedAt: Date;
  siteId: string;
  seoTitle: string | null;
  seoDescription: string | null;
  visibility: string;
  noIndex: boolean;
  site: { name: string };
}

const seoState = (p: ManagedPageRow) => (p.noIndex ? "hidden" : p.seoTitle && p.seoDescription ? "good" : "missing");
const STATUS_LABEL: Record<string, string> = { DRAFT: "Draft", IN_REVIEW: "In review", SCHEDULED: "Scheduled", PUBLISHED: "Published", ARCHIVED: "Archived" };
const fmt = (d: Date) => new Date(d).toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric", timeZone: "UTC" });

interface Props {
  pages: ManagedPageRow[];
  /** `/dashboard/<kind>/pages` */
  base: string;
  siteId: string | null;
  canReorder: boolean;
  canCopy: boolean;
  canCreate: boolean;
  /** false = read-only access: the row action says "View Page". */
  canEdit?: boolean;
  /** Set as homepage and Delete Page (publish permission). */
  canPublish?: boolean;
  q?: string;
  status?: string;
}

export function ManagedPageList({ pages, base, siteId, canReorder, canCopy, canCreate, canEdit = true, canPublish = false, q, status }: Props) {
  const { pending, msg, run } = useRun();
  const [selected, setSelected] = useState<string[]>([]);
  const [order, setOrder] = useState(pages.map((p) => p.id));
  const [dragId, setDragId] = useState<string | null>(null);
  const [menu, setMenu] = useState<string | null>(null);
  const [hint, setHint] = useState(false);
  const [armed, setArmed] = useState<string | null>(null);
  const formRef = useRef<HTMLFormElement>(null);
  const byId = new Map(pages.map((p) => [p.id, p]));
  const rows = order.map((id) => byId.get(id)).filter((p): p is ManagedPageRow => Boolean(p)).sort((a, b) => Number(b.slug === "home") - Number(a.slug === "home"));
  const reorderEnabled = canReorder && !!siteId;
  const firstMovable = rows.findIndex((r) => r.slug !== "home");
  const root = base.replace(/\/pages$/, "");

  const commitOrder = (next: string[]) => {
    setOrder(next);
    if (siteId) run(() => reorderPagesAction(siteId, next));
  };
  const moveRow = (id: string, delta: number) => {
    // The homepage always stays on top, so moves only swap with other pages.
    const movable = order.filter((x) => byId.get(x)?.slug !== "home");
    const i = movable.indexOf(id);
    const j = i + delta;
    if (i < 0 || j < 0 || j >= movable.length) return;
    const a = order.indexOf(movable[i]!), b = order.indexOf(movable[j]!);
    const next = [...order];
    [next[a], next[b]] = [next[b]!, next[a]!];
    commitOrder(next);
  };
  const dropOn = (toId: string) => {
    if (!dragId || dragId === toId) return;
    const next = order.filter((x) => x !== dragId);
    next.splice(next.indexOf(toId) + (order.indexOf(dragId) < order.indexOf(toId) ? 1 : 0), 0, dragId);
    setDragId(null);
    commitOrder(next);
  };

  return (
    <div className="space-y-5">
      <div className="flex flex-wrap items-center gap-3">
        <h1 className="mr-auto text-5xl font-bold tracking-tight text-[var(--ed-ink)]">Pages</h1>
        {canCreate ? <Link href={`${base}/new`} className={pillClass("outline")}>Add Page</Link> : null}
        {canCopy ? (
          <button type="button" title="Copy the ticked pages to another website" disabled={pending} onClick={() => (selected.length === 0 ? setHint(true) : run(() => copyPagesAction(selected), () => setSelected([])))} className={pillClass("outline")}>
            Copy Pages{selected.length ? ` (${selected.length})` : ""}
          </button>
        ) : null}
      </div>
      <form ref={formRef} action={base} method="get" role="search" className="flex flex-wrap items-center justify-between gap-3">
        <div className="relative">
          <label htmlFor="pages-q" className="sr-only">Search pages</label>
          <input id="pages-q" name="q" defaultValue={q ?? ""} placeholder="Search…" className="h-11 w-52 rounded-xl border border-[var(--ed-line)] bg-white pl-3 pr-10 text-sm text-[var(--ed-ink)] placeholder:text-[var(--ed-soft)]" />
          <Link href={status ? `${base}?status=${status}` : base} aria-label="Clear search" className="absolute right-2 top-1/2 inline-flex size-7 -translate-y-1/2 items-center justify-center text-[var(--ed-blue)]"><X className="size-4" aria-hidden /></Link>
        </div>
        <div className="relative">
          <label htmlFor="pages-status" className="sr-only">Status</label>
          <select id="pages-status" name="status" defaultValue={status ?? ""} onChange={() => formRef.current?.requestSubmit()} className="h-11 w-44 appearance-none rounded-xl border border-[var(--ed-line)] bg-white pl-3 pr-9 text-sm text-[var(--ed-ink)]">
            <option value="">Any Status</option>
            {PAGE_STATUSES.map((s) => <option key={s} value={s}>{STATUS_LABEL[s] ?? s}</option>)}
          </select>
          <ChevronDown className="pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-[var(--ed-soft)]" aria-hidden />
        </div>
        <noscript><button type="submit" className={pillClass("dark")}>Search</button></noscript>
      </form>
      <StatusLine msg={msg} />
      {hint && selected.length === 0 ? <p role="status" className="text-sm text-[var(--ed-soft)]">Tick one or more pages first, then choose Copy Pages.</p> : null}
      {reorderEnabled ? null : canReorder ? null : <p className="text-xs text-[var(--ed-soft)]">Open one website and clear the search to reorder pages.</p>}

      {rows.length === 0 ? (
        <div className="rounded-3xl bg-white px-6 py-14 text-center">
          <p className="text-lg font-bold text-[var(--ed-ink)]">No pages match</p>
          <p className="mt-1 text-sm text-[var(--ed-soft)]">{q || status ? "Try a different search or status." : "Add your first page to get started."}</p>
        </div>
      ) : (
        <ul className="space-y-3" aria-label="Pages">
          {rows.map((p, i) => {
            const seo = seoState(p);
            const isHome = p.slug === "home";
            return (
              <li
                key={p.id}
                onDragOver={(e) => { if (dragId) e.preventDefault(); }}
                onDrop={(e) => { e.preventDefault(); dropOn(p.id); }}
                className={cn("flex flex-wrap items-center gap-3 rounded-xl bg-white px-4 py-2.5 shadow-sm", dragId === p.id && "opacity-50")}
              >
                {isHome ? (
                  <span className="grid size-9 shrink-0 place-items-center text-[var(--ed-soft)]"><Home className="size-5" role="img" aria-label="Home page" /></span>
                ) : reorderEnabled ? (
                  <button type="button" aria-label={`Drag ${p.title} to reorder`} draggable onDragStart={(e) => { setDragId(p.id); e.dataTransfer.effectAllowed = "move"; }} onDragEnd={() => setDragId(null)} className="inline-flex size-9 shrink-0 cursor-grab items-center justify-center rounded-md bg-[var(--ed-grey)] text-[var(--ed-soft)]"><GripVertical className="size-4" aria-hidden /></button>
                ) : null}
                {canCopy && !isHome ? <input type="checkbox" className="size-5 shrink-0" aria-label={`Select ${p.title}`} checked={selected.includes(p.id)} onChange={(e) => setSelected(e.target.checked ? [...selected, p.id] : selected.filter((x) => x !== p.id))} /> : null}
                {p.status !== "PUBLISHED" ? <span className="shrink-0 rounded-full border border-[var(--ed-line)] bg-[#e9ebee] px-3 py-1 text-xs font-bold text-[var(--ed-ink)]">{STATUS_LABEL[p.status] ?? p.status}</span> : null}
                <div className="min-w-0 flex-1">
                  <Link href={`${base}/${p.id}`} className="block truncate text-sm text-[var(--ed-ink)] hover:underline">{p.title}</Link>
                  <span className="sr-only">/{p.slug === "home" ? "" : p.slug}, updated {fmt(p.updatedAt)}</span>
                  {!siteId ? <span className="block truncate text-xs text-[var(--ed-soft)]">{p.site.name}</span> : null}
                </div>
                <span className="inline-flex shrink-0 cursor-default items-center gap-1.5 rounded-full border border-[var(--ed-line)] px-2.5 py-1 text-[11px] font-semibold text-[var(--ed-soft)]" title={seo === "good" ? "Meta title and description are set" : seo === "hidden" ? "Search engines are asked not to index this page" : "Add a meta title and description"}>
                  <span aria-hidden className={cn("size-2 rounded-full", seo === "good" ? "bg-[var(--ed-green)]" : seo === "hidden" ? "bg-[#6b7785]" : "bg-[var(--ed-pink)]")} />
                  SEO<span className="sr-only">: {seo === "good" ? "ready" : seo === "hidden" ? "not indexed" : "needs attention"}</span>
                </span>
                <div className="relative inline-flex">
                  <Link href={`${base}/${p.id}`} className={pillClass("grey", "rounded-r-none pr-3")}>{canEdit ? "Edit Page" : "View Page"}</Link>
                  <button type="button" aria-label={`More actions for ${p.title}`} aria-haspopup="menu" aria-expanded={menu === p.id} onClick={() => setMenu(menu === p.id ? null : p.id)} className={pillClass("grey", "rounded-l-none border-l border-black/10 px-2.5")}><ChevronDown className="size-3.5" aria-hidden /></button>
                  {menu === p.id ? (
                    <div role="menu" className="absolute right-0 top-full z-20 mt-1 w-48 overflow-hidden rounded-2xl bg-white shadow-xl ring-1 ring-black/10" onMouseLeave={() => { setMenu(null); setArmed(null); }}>
                      {reorderEnabled && !isHome ? (
                        <>
                          <button type="button" role="menuitem" disabled={pending || i <= firstMovable} className="block w-full px-4 py-2.5 text-left text-sm font-semibold text-[var(--ed-ink)] hover:bg-[#eef1f4] disabled:opacity-40" onClick={() => { setMenu(null); moveRow(p.id, -1); }}>Move up</button>
                          <button type="button" role="menuitem" disabled={pending || i === rows.length - 1} className="block w-full px-4 py-2.5 text-left text-sm font-semibold text-[var(--ed-ink)] hover:bg-[#eef1f4] disabled:opacity-40" onClick={() => { setMenu(null); moveRow(p.id, 1); }}>Move down</button>
                        </>
                      ) : null}
                      <a role="menuitem" href={`/preview/${p.id}`} target="_blank" rel="noopener noreferrer" className="block px-4 py-2.5 text-sm font-semibold text-[var(--ed-ink)] hover:bg-[#eef1f4]" onClick={() => setMenu(null)}>Preview Page ↗</a>
                      {canPublish && p.slug !== "home" ? <button type="button" role="menuitem" disabled={pending} className="block w-full px-4 py-2.5 text-left text-sm font-semibold text-[var(--ed-ink)] hover:bg-[#eef1f4] disabled:opacity-50" onClick={() => { setMenu(null); run(() => setHomepageAction(p.id)); }}>Set as Homepage</button> : null}
                      {canCopy ? <button type="button" role="menuitem" disabled={pending} className="block w-full px-4 py-2.5 text-left text-sm font-semibold text-[var(--ed-ink)] hover:bg-[#eef1f4] disabled:opacity-50" onClick={() => { setMenu(null); run(() => duplicatePageAction(root, p.id)); }}>Copy Page</button> : null}
                      {canPublish && p.slug !== "home" ? (
                        armed === p.id ? (
                          <div className="flex gap-1 p-2"><button type="button" role="menuitem" disabled={pending} className="rounded-full bg-[var(--ed-pink)] px-3 py-1.5 text-xs font-bold text-white" onClick={() => { setArmed(null); setMenu(null); run(() => deletePageRowAction(p.id)); }}>Confirm delete</button><button type="button" className="rounded-full px-3 py-1.5 text-xs font-semibold hover:bg-[#eef1f4]" onClick={() => setArmed(null)}>Cancel</button></div>
                        ) : <button type="button" role="menuitem" className="block w-full px-4 py-2.5 text-left text-sm font-semibold text-[var(--ed-ink)] hover:bg-[#eef1f4] disabled:opacity-50" onClick={() => setArmed(p.id)}>Delete Page</button>
                      ) : null}
                    </div>
                  ) : null}
                </div>
              </li>
            );
          })}
        </ul>
      )}
    </div>
  );
}
