"use client";

import { useEffect, useState } from "react";
import { CheckSquare, Square, Users } from "lucide-react";
import { bulkSetMemberStatus } from "./actions";

type Props = {
  memberIds: string[];
  selfId: string;
};

const STATUS_OPTIONS = [
  { value: "active", label: "Activate" },
  { value: "suspended", label: "Suspend" },
  { value: "rejected", label: "Reject" },
  { value: "pending", label: "Back to pending" },
];

/**
 * Toolbar that floats above the member list. Relies on the checkbox
 * elements in the list having `data-member-select` attribute with the row
 * id; this keeps the parent page a server component while still letting
 * users pick specific rows to act on.
 */
export function BulkActionBar({ memberIds, selfId }: Props) {
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [pending, setPending] = useState(false);

  useEffect(() => {
    const onChange = (e: Event) => {
      const target = e.target as HTMLInputElement;
      if (!target.matches("[data-member-select]")) return;
      const id = target.dataset.memberSelect!;
      setSelected((prev) => {
        const next = new Set(prev);
        if (target.checked) next.add(id);
        else next.delete(id);
        return next;
      });
    };
    document.addEventListener("change", onChange);
    return () => document.removeEventListener("change", onChange);
  }, []);

  const toggleAll = (checked: boolean) => {
    const next = new Set<string>();
    if (checked) {
      for (const id of memberIds) {
        if (id === selfId) continue;
        next.add(id);
      }
    }
    setSelected(next);
    for (const el of document.querySelectorAll<HTMLInputElement>(
      "[data-member-select]",
    )) {
      if (el.dataset.memberSelect === selfId) continue;
      el.checked = checked;
    }
  };

  async function apply(status: string) {
    if (selected.size === 0) return;
    const confirm = window.confirm(
      `Apply status "${status}" to ${selected.size} member${
        selected.size === 1 ? "" : "s"
      }? This cannot be undone.`,
    );
    if (!confirm) return;
    setPending(true);
    const formData = new FormData();
    for (const id of selected) formData.append("ids", id);
    formData.set("status", status);
    try {
      await bulkSetMemberStatus(formData);
      setSelected(new Set());
      for (const el of document.querySelectorAll<HTMLInputElement>(
        "[data-member-select]",
      )) {
        el.checked = false;
      }
    } catch (err) {
      window.alert(
        err instanceof Error ? err.message : "Bulk update failed",
      );
    } finally {
      setPending(false);
    }
  }

  const visible = memberIds.filter((id) => id !== selfId).length;

  return (
    <div
      className="sticky top-4 z-10 mb-4 flex flex-wrap items-center justify-between gap-3 rounded-xl border border-[var(--color-line)] bg-white p-3 shadow-sm"
      role="region"
      aria-label="Bulk actions"
    >
      <div className="flex items-center gap-3 text-[13px]">
        <button
          type="button"
          onClick={() => toggleAll(selected.size < visible)}
          className="inline-flex items-center gap-1.5 rounded-md border border-[var(--color-line)] bg-white px-2.5 py-1 text-[12px] font-semibold text-[var(--color-ink)] hover:border-[var(--color-blue)] hover:text-[var(--color-blue)]"
        >
          {selected.size > 0 && selected.size >= visible ? (
            <CheckSquare className="h-3.5 w-3.5" aria-hidden />
          ) : (
            <Square className="h-3.5 w-3.5" aria-hidden />
          )}
          {selected.size > 0 && selected.size >= visible
            ? "Deselect all"
            : "Select all"}
        </button>
        <span
          className="inline-flex items-center gap-1.5 text-[12px] font-semibold text-[var(--color-slate)]"
          aria-live="polite"
        >
          <Users className="h-3.5 w-3.5" aria-hidden />
          {selected.size} selected
        </span>
      </div>
      <div className="flex flex-wrap items-center gap-2">
        {STATUS_OPTIONS.map((opt) => (
          <button
            key={opt.value}
            type="button"
            disabled={selected.size === 0 || pending}
            onClick={() => apply(opt.value)}
            className="inline-flex items-center gap-1 rounded-md border border-[var(--color-line)] bg-white px-3 py-1 text-[12px] font-semibold text-[var(--color-ink)] hover:border-[var(--color-blue)] hover:text-[var(--color-blue)] disabled:cursor-not-allowed disabled:opacity-40"
          >
            {opt.label}
          </button>
        ))}
      </div>
    </div>
  );
}
