﻿"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import toast, { Toaster } from "react-hot-toast";
import { IdCardDisplay, type CardData } from "@/components/IdCardDisplay";

const API = process.env.NEXT_PUBLIC_API_URL || "http://localhost:5000/api";
const PAGE_SIZE = 8;

type Person = { id: number; name: string; phone: string; email: string; approval_status: string };
type ViewTarget = { type: "member" | "volunteer"; id: number; name: string };
type Tab = "members" | "volunteers";

function cardLabel(type: "member" | "volunteer", id: number) {
  return `SKSF-${type === "member" ? "M" : "V"}-${String(id).padStart(5, "0")}`;
}

function initials(name: string) {
  return name
    .split(/\s+/)
    .filter(Boolean)
    .map((w) => w[0])
    .slice(0, 2)
    .join("")
    .toUpperCase();
}

function pageNumbers(total: number, current: number) {
  const count = Math.min(total, 5);
  let start = Math.max(1, current - Math.floor(count / 2));
  const end = Math.min(total, start + count - 1);
  start = Math.max(1, end - count + 1);
  return Array.from({ length: end - start + 1 }, (_, i) => start + i);
}

export function AdminIdCards() {
  const [members, setMembers] = useState<Person[]>([]);
  const [volunteers, setVolunteers] = useState<Person[]>([]);
  const [loading, setLoading] = useState(true);
  const [message, setMessage] = useState("");
  const [tab, setTab] = useState<Tab>("members");
  const [search, setSearch] = useState("");
  const [page, setPage] = useState(1);
  const [shareModal, setShareModal] = useState<{ type: "member" | "volunteer"; id: number; name: string; email: string } | null>(null);
  const [shareEmail, setShareEmail] = useState("");
  const [sending, setSending] = useState(false);
  const [sentCards, setSentCards] = useState<Record<string, boolean>>({});
  const [viewModal, setViewModal] = useState<ViewTarget | null>(null);
  const [cardData, setCardData] = useState<CardData | null>(null);
  const [viewLoading, setViewLoading] = useState(false);
  const [viewError, setViewError] = useState("");
  const [viewPublicUrl, setViewPublicUrl] = useState("");

  const token = useMemo(() => {
    if (typeof window === "undefined") return "";
    return localStorage.getItem("ngo_admin_token") || "";
  }, []);

  const headers = useMemo(() => ({ Authorization: "Bearer " + token }), [token]);

  const loadData = useCallback(async () => {
    try {
      const [membersRes, volunteersRes] = await Promise.all([
        fetch(API + "/admin/members", { headers: headers }),
        fetch(API + "/admin/volunteers", { headers: headers }),
      ]);
      if (membersRes.ok) {
        const all = await membersRes.json();
        setMembers(all.filter((m: Person) => m.approval_status === "approved"));
      }
      if (volunteersRes.ok) {
        const all = await volunteersRes.json();
        setVolunteers(all.filter((v: Person) => v.approval_status === "approved"));
      }
    } catch {
      setMessage("Failed to load data");
    }
    setLoading(false);
  }, [headers]);

  useEffect(() => {
    const t = window.setTimeout(() => loadData(), 0);
    return () => window.clearTimeout(t);
  }, [loadData]);

  useEffect(() => {
    if (!members.length && !volunteers.length) return;
    const all = [
      ...members.map(m => fetch(API + "/admin/id-cards/members/" + m.id + "/share-status", { headers }).then(r => r.json()).then(d => { if (d.sent) setSentCards(p => ({ ...p, ["member-" + m.id]: true })); }).catch(() => {})),
      ...volunteers.map(v => fetch(API + "/admin/id-cards/volunteers/" + v.id + "/share-status", { headers }).then(r => r.json()).then(d => { if (d.sent) setSentCards(p => ({ ...p, ["volunteer-" + v.id]: true })); }).catch(() => {})),
    ];
    Promise.all(all);
  }, [members, volunteers, headers]);

  const openViewCard = async (type: "member" | "volunteer", id: number, name: string) => {
    setViewModal({ type, id, name });
    setCardData(null);
    setViewError("");
    setViewPublicUrl("");
    setViewLoading(true);
    try {
      const base = type === "member" ? "members" : "volunteers";
      const [cardRes, linkRes] = await Promise.all([
        fetch(API + "/admin/id-cards/" + base + "/" + id + "/view", { headers }),
        fetch(API + "/admin/id-cards/" + base + "/" + id + "/share-link", { headers }),
      ]);
      const json = await cardRes.json().catch(() => ({}));
      if (!cardRes.ok) {
        setViewError(json.message || "Could not load the ID card.");
        setViewLoading(false);
        return;
      }
      setCardData(json);
      if (linkRes.ok) {
        const link = await linkRes.json().catch(() => null);
        if (link && link.url) setViewPublicUrl(link.url);
      }
    } catch {
      setViewError("Network error. Please try again.");
    }
    setViewLoading(false);
  };

  const shareCard = async () => {
    if (!shareModal) return;
    if (!shareEmail.trim()) {
      toast.error("Email is required");
      return;
    }
    setMessage("");
    setSending(true);
    const loadingToast = toast.loading("Sending ID card link...", { duration: Infinity });
    try {
      const base = shareModal.type === "member" ? "members" : "volunteers";
      const res = await fetch(API + "/admin/id-cards/" + base + "/" + shareModal.id + "/share", {
        method: "POST",
        headers: { "Content-Type": "application/json", Authorization: "Bearer " + token },
        body: JSON.stringify({ email: shareEmail }),
      });
      toast.dismiss(loadingToast);
      if (!res.ok) {
        const err = await res.json();
        toast.error(err.message || "Failed to send");
        return;
      }
      toast.success("ID card link sent to " + shareEmail);
      setSentCards(prev => ({ ...prev, [shareModal.type + "-" + shareModal.id]: true }));
      setShareModal(null);
      setShareEmail("");
    } catch {
      toast.dismiss(loadingToast);
      toast.error("Failed to send email");
    } finally {
      setSending(false);
    }
  };

  const activeList = tab === "members" ? members : volunteers;
  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return activeList;
    return activeList.filter((p) => {
      const name = p.name.toLowerCase();
      const number = cardLabel(tab === "members" ? "member" : "volunteer", p.id).toLowerCase();
      const rawId = String(p.id);
      const phone = (p.phone || "").toLowerCase();
      const email = (p.email || "").toLowerCase();
      return name.includes(q) || number.includes(q) || rawId === q || phone.includes(q) || email.includes(q);
    });
  }, [activeList, search, tab]);

  const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE));
  const safePage = Math.min(page, totalPages);
  const pageStart = (safePage - 1) * PAGE_SIZE;
  const pageItems = filtered.slice(pageStart, pageStart + PAGE_SIZE);

  const switchTab = (next: Tab) => {
    setTab(next);
    setPage(1);
    setSearch("");
  };

  if (loading) {
    return (
      <div className="mx-auto max-w-7xl">
        <div className="flex items-center gap-2.5 rounded-md border border-[var(--color-hairline)] bg-white p-3 text-[11.5px] font-black text-[var(--color-ink)] shadow-sm">
          <span className="h-3.5 w-3.5 animate-spin rounded-full border-2 border-[var(--color-hairline)] border-t-[var(--color-primary)]" />
          Loading approved members and volunteers...
        </div>
      </div>
    );
  }

  return (
    <div className="mx-auto max-w-7xl">
      <div className="mb-5 flex flex-wrap items-end justify-between gap-3">
        <div>
          <p className="text-[10px] font-black uppercase tracking-[0.14em] text-[var(--color-primary)]">Identity</p>
          <h1 className="mt-0.5 text-xl font-black text-[var(--color-ink)] md:text-2xl">ID Cards</h1>
          <p className="mt-1 max-w-2xl text-[11.5px] font-medium text-[var(--color-ink-mute)]">
            ID cards are rendered as a stylish, printable HTML page on the public website. Members verify with their card number and date of birth.
          </p>
        </div>
        <a
          href="/id-card"
          target="_blank"
          rel="noopener noreferrer"
          className="flex items-center gap-1.5 rounded-md bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-deep)] px-3.5 py-2 text-[11.5px] font-black text-white shadow-[0_8px_18px_rgba(91,98,240,0.3)] transition hover:brightness-105"
        >
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
            <polyline points="15 3 21 3 21 9" />
            <line x1="10" y1="14" x2="21" y2="3" />
          </svg>
          Open Public ID Card Page
        </a>
      </div>

      {message ? <p className="mb-4 rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] p-3 text-[11.5px] font-bold text-[var(--color-ink)]">{message}</p> : null}

      {/* â”€â”€ Tabs + search â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
      <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
        <div className="inline-flex rounded-lg border border-[var(--color-hairline)] bg-white p-1 shadow-sm">
          <button
            onClick={() => switchTab("members")}
            className={"flex items-center gap-2 rounded-md px-4 py-2 text-[12px] font-black transition " + (tab === "members" ? "bg-gradient-to-r from-[var(--color-primary-deep)] to-[var(--color-primary-deep)] text-white shadow-[0_6px_14px_rgba(26,107,74,0.28)]" : "text-[var(--color-ink-mute)] hover:bg-[var(--color-canvas-soft)] hover:text-[var(--color-ink)]")}
          >
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
              <circle cx="9" cy="7" r="4" />
              <path d="M23 21v-2a4 4 0 0 0-3-3.87" />
              <path d="M16 3.13a4 4 0 0 1 0 7.75" />
            </svg>
            Members
            <span className={"rounded-full px-1.5 py-0.5 text-[10px] font-black " + (tab === "members" ? "bg-white/20 text-white" : "bg-[var(--color-canvas-soft)] text-[var(--color-primary)]")}>{members.length}</span>
          </button>
          <button
            onClick={() => switchTab("volunteers")}
            className={"flex items-center gap-2 rounded-md px-4 py-2 text-[12px] font-black transition " + (tab === "volunteers" ? "bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-deep)] text-white shadow-[0_6px_14px_rgba(91,98,240,0.3)]" : "text-[var(--color-ink-mute)] hover:bg-[var(--color-canvas-soft)] hover:text-[var(--color-ink)]")}
          >
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
              <circle cx="9" cy="7" r="4" />
              <path d="M22 21v-2a4 4 0 0 0-3-3.87" />
              <path d="M16 3.13a4 4 0 0 1 0 7.75" />
            </svg>
            Volunteers
            <span className={"rounded-full px-1.5 py-0.5 text-[10px] font-black " + (tab === "volunteers" ? "bg-white/20 text-white" : "bg-[var(--color-canvas-soft)] text-[var(--color-primary)]")}>{volunteers.length}</span>
          </button>
        </div>

        <div className="relative w-full sm:w-72">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-ink-mute)]">
            <circle cx="11" cy="11" r="8" />
            <line x1="21" y1="21" x2="16.65" y2="16.65" />
          </svg>
          <input
            type="text"
            value={search}
            onChange={(e) => { setSearch(e.target.value); setPage(1); }}
            placeholder={"Search by name or " + (tab === "members" ? "member" : "volunteer") + " number..."}
            className="w-full rounded-lg border border-[var(--color-hairline)] bg-white py-2 pl-9 pr-8 text-[12px] font-semibold text-[var(--color-ink)] shadow-sm outline-none transition focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary)]/15"
          />
          {search ? (
            <button onClick={() => setSearch("")} className="absolute right-2.5 top-1/2 -translate-y-1/2 rounded-full p-0.5 text-[var(--color-ink-mute)] transition hover:bg-[var(--color-canvas-soft)] hover:text-[var(--color-ink)]" aria-label="Clear search">
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                <line x1="18" y1="6" x2="6" y2="18" />
                <line x1="6" y1="6" x2="18" y2="18" />
              </svg>
            </button>
          ) : null}
        </div>
      </div>

      {/* â”€â”€ Table â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
      <section className="overflow-hidden rounded-xl border border-[var(--color-hairline)] bg-white shadow-sm">
        <div className="flex flex-wrap items-center justify-between gap-2 border-b border-[var(--color-hairline)] bg-gradient-to-r from-[var(--color-canvas-soft)] to-[var(--color-canvas-soft)] px-4 py-3">
          <div className="flex items-center gap-2.5">
            <span className={"grid h-7 w-7 place-items-center rounded-md text-[12px] font-black text-white " + (tab === "members" ? "bg-gradient-to-br from-[var(--color-primary-deep)] to-[var(--color-primary-deep)]" : "bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-primary-deep)]")}>
              {tab === "members" ? "M" : "V"}
            </span>
            <h2 className="text-[13.5px] font-black text-[var(--color-ink)]">
              {tab === "members" ? "Members" : "Volunteers"}
              <span className="ml-1.5 text-[10.5px] font-bold text-[var(--color-ink-mute)]">Â· {filtered.length} {filtered.length === 1 ? "record" : "records"}</span>
            </h2>
          </div>
          <span className="rounded-full border border-[var(--color-hairline-cool)] bg-white px-2.5 py-1 text-[10px] font-black uppercase tracking-[0.08em] text-[var(--color-ink-mute)]">
            Approved only
          </span>
        </div>

        <div className="overflow-x-auto">
          <table className="w-full min-w-[820px] border-collapse text-left text-[12px]">
            <thead>
              <tr className="border-b border-[var(--color-hairline)] bg-[var(--color-canvas-soft)]">
                <th className="px-4 py-3 text-[10px] font-black uppercase tracking-[0.08em] text-[var(--color-ink-mute)]">Person</th>
                <th className="px-4 py-3 text-[10px] font-black uppercase tracking-[0.08em] text-[var(--color-ink-mute)]">Card No</th>
                <th className="px-4 py-3 text-[10px] font-black uppercase tracking-[0.08em] text-[var(--color-ink-mute)]">Phone</th>
                <th className="px-4 py-3 text-[10px] font-black uppercase tracking-[0.08em] text-[var(--color-ink-mute)]">Email</th>
                <th className="px-4 py-3 text-[10px] font-black uppercase tracking-[0.08em] text-[var(--color-ink-mute)]">Status</th>
                <th className="px-4 py-3 text-right text-[10px] font-black uppercase tracking-[0.08em] text-[var(--color-ink-mute)]">Actions</th>
              </tr>
            </thead>
            <tbody>
              {pageItems.length === 0 ? (
                <tr>
                  <td colSpan={6} className="px-4 py-14 text-center">
                    <div className="flex flex-col items-center gap-3">
                      <span className="grid h-12 w-12 place-items-center rounded-full bg-[var(--color-canvas-soft)] text-[var(--color-ink-mute)]">
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                          <circle cx="11" cy="11" r="8" />
                          <line x1="21" y1="21" x2="16.65" y2="16.65" />
                        </svg>
                      </span>
                      <div>
                        <p className="text-[13px] font-black text-[var(--color-ink)]">{search ? "No matching records" : "No " + tab + " found"}</p>
                        <p className="mt-0.5 text-[11.5px] font-semibold text-[var(--color-ink-mute)]">
                          {search ? "Try a different name or number." : "Add and approve " + tab + " to see them here."}
                        </p>
                      </div>
                    </div>
                  </td>
                </tr>
              ) : pageItems.map((p) => (
                <tr key={p.id} className="group border-b border-[var(--color-hairline)] bg-white align-top transition hover:bg-[var(--color-canvas-soft)]">
                  <td className="px-4 py-3">
                    <div className="flex items-center gap-3">
                      <span className={"grid h-9 w-9 shrink-0 place-items-center rounded-full text-[12px] font-black text-white shadow-sm " + (tab === "members" ? "bg-gradient-to-br from-[var(--color-primary-deep)] to-[var(--color-primary-deep)]" : "bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-primary-deep)]")}>
                        {initials(p.name)}
                      </span>
                      <div className="min-w-0">
                        <p className="truncate text-[12.5px] font-black text-[var(--color-ink)]">{p.name}</p>
                        <p className="truncate text-[10.5px] font-semibold text-[var(--color-ink-mute)]">
                          {tab === "members" ? "Member" : "Volunteer"} Â· ID {p.id}
                        </p>
                      </div>
                    </div>
                  </td>
                  <td className="px-4 py-3">
                    <span className="inline-flex rounded-md border border-[var(--color-hairline-cool)] bg-[var(--color-canvas-soft)] px-2 py-1 font-mono text-[11px] font-bold text-[var(--color-primary)]">
                      {cardLabel(tab === "members" ? "member" : "volunteer", p.id)}
                    </span>
                  </td>
                  <td className="px-4 py-3 text-[12px] font-semibold text-[var(--color-ink)]">{p.phone || "-"}</td>
                  <td className="px-4 py-3 text-[12px] text-[var(--color-ink-mute)]">
                    <span className="block max-w-[190px] truncate">{p.email || "-"}</span>
                  </td>
                  <td className="px-4 py-3">
                    <span className="inline-flex items-center gap-1.5 rounded-full bg-[var(--color-canvas-soft)] px-2.5 py-1 text-[10.5px] font-black text-[var(--color-primary-deep)]">
                      <span className="h-1.5 w-1.5 rounded-full bg-[var(--color-primary-deep)]" />
                      Approved
                    </span>
                  </td>
                  <td className="px-4 py-3">
                    <div className="flex justify-end gap-1.5">
                      <button
                        onClick={() => openViewCard(tab === "members" ? "member" : "volunteer", p.id, p.name)}
                        className="flex items-center gap-1.5 rounded-md bg-[var(--color-primary-deep)] px-3 py-1.5 text-[11px] font-black text-white shadow-[0_4px_10px_rgba(15,107,79,0.2)] transition hover:bg-[var(--color-canvas-night)]"
                      >
                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
                          <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
                          <circle cx="12" cy="12" r="3" />
                        </svg>
                        View Card
                      </button>
                      <button
                        onClick={async () => {
                          setShareModal({ type: tab === "members" ? "member" : "volunteer", id: p.id, name: p.name, email: p.email || "" });
                          setShareEmail(p.email || "");
                          try {
                            const r = await fetch(API + "/admin/id-cards/" + (tab === "members" ? "members" : "volunteers") + "/" + p.id + "/share-status", { headers });
                            const d = await r.json();
                            setSentCards(prev => ({ ...prev, [tab.slice(0, -1) + "-" + p.id]: d.sent }));
                          } catch { /* ignore */ }
                        }}
                        className={"flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-[11px] font-black transition " + (sentCards[tab.slice(0, -1) + "-" + p.id] ? "border-[#d97706] bg-[#d97706] text-black hover:bg-[#b45309]" : "border-[var(--color-hairline)] bg-white text-[var(--color-ink)] hover:border-[var(--color-primary-deep)] hover:text-[var(--color-primary-deep)]")}
                      >
                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
                          <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" />
                          <polyline points="22,6 12,13 2,6" />
                        </svg>
                        {sentCards[tab.slice(0, -1) + "-" + p.id] ? "Share Again" : "Share"}
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        {/* â”€â”€ Pagination â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
        {filtered.length > PAGE_SIZE ? (
          <div className="flex flex-wrap items-center justify-between gap-3 border-t border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] px-4 py-3">
            <p className="text-[11px] font-bold text-[var(--color-ink-mute)]">
              Showing <span className="font-black text-[var(--color-ink)]">{pageStart + 1}â€“{Math.min(pageStart + PAGE_SIZE, filtered.length)}</span> of <span className="font-black text-[var(--color-ink)]">{filtered.length}</span> {tab}
            </p>
            <div className="flex items-center gap-1">
              <button
                onClick={() => setPage(safePage - 1)}
                disabled={safePage <= 1}
                className="flex h-8 w-8 items-center justify-center rounded-md border border-[var(--color-hairline)] bg-white text-[var(--color-ink)] transition hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] disabled:pointer-events-none disabled:opacity-40"
                aria-label="Previous page"
              >
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><polyline points="15 18 9 12 15 6" /></svg>
              </button>
              {pageNumbers(totalPages, safePage).map((n) => (
                <button
                  key={n}
                  onClick={() => setPage(n)}
                  className={"h-8 min-w-8 rounded-md px-2 text-[11.5px] font-black transition " + (n === safePage ? "bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-deep)] text-white shadow-[0_4px_10px_rgba(91,98,240,0.28)]" : "border border-[var(--color-hairline)] bg-white text-[var(--color-ink)] hover:border-[var(--color-primary)] hover:text-[var(--color-primary)]")}
                >
                  {n}
                </button>
              ))}
              <button
                onClick={() => setPage(safePage + 1)}
                disabled={safePage >= totalPages}
                className="flex h-8 w-8 items-center justify-center rounded-md border border-[var(--color-hairline)] bg-white text-[var(--color-ink)] transition hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] disabled:pointer-events-none disabled:opacity-40"
                aria-label="Next page"
              >
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 18 15 12 9 6" /></svg>
              </button>
            </div>
          </div>
        ) : null}
      </section>

      {viewModal ? (
        <div className="fixed inset-0 z-[80] grid place-items-center overflow-y-auto bg-black/45 p-4 backdrop-blur-sm" onClick={() => setViewModal(null)}>
          <section className="w-full max-w-3xl rounded-md bg-[var(--color-canvas-soft)] p-4 shadow-2xl" onClick={(e) => e.stopPropagation()}>
            <div className="flex items-center justify-between gap-3">
              <div>
                <h2 className="text-[13.5px] font-black text-[var(--color-ink)]">ID Card â€” {viewModal.name}</h2>
                <p className="text-[11.5px] font-semibold text-[var(--color-ink-mute)]">{"SKSF-" + (viewModal.type === "member" ? "M" : "V") + "-" + String(viewModal.id).padStart(5, "0")}</p>
              </div>
              <div className="flex items-center gap-2">
                <a
                  href={viewPublicUrl || ("/id-card?type=" + viewModal.type + "&id=" + viewModal.id)}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="rounded-md border border-[var(--color-hairline)] bg-white px-3 py-2 text-[11.5px] font-black text-[var(--color-ink)] transition hover:border-[var(--color-primary)] hover:text-[var(--color-primary)]"
                >
                  Open Direct Link
                </a>
                <button
                  onClick={() => {
                    if (!viewPublicUrl) return;
                    const w = window.open(viewPublicUrl, "_blank");
                    if (w) w.onload = () => w.print();
                  }}
                  disabled={!cardData || !viewPublicUrl}
                  className="rounded-md bg-gradient-to-r from-[var(--color-primary-deep)] to-[var(--color-primary-deep)] px-4 py-2 text-[11.5px] font-black text-white shadow-[0_8px_18px_rgba(26,107,74,0.28)] transition hover:brightness-105 disabled:opacity-50"
                  title="Opens the card page and prints the front (page 1) and back (page 2)"
                >
                  Print
                </button>
                <button onClick={() => setViewModal(null)} className="rounded-md border border-[var(--color-hairline)] bg-white px-3 py-2 text-[11.5px] font-black text-[var(--color-ink)] transition hover:border-[var(--color-primary)] hover:text-[var(--color-primary)]">Close</button>
              </div>
            </div>

            <div className="mt-4">
              {viewLoading ? (
                <div className="flex items-center justify-center gap-2.5 rounded-md border border-[var(--color-hairline)] bg-white p-8 text-[11.5px] font-black text-[var(--color-ink)] shadow-sm">
                  <span className="h-3.5 w-3.5 animate-spin rounded-full border-2 border-[var(--color-hairline)] border-t-[var(--color-primary)]" />
                  Loading ID card...
                </div>
              ) : viewError ? (
                <p className="rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] p-4 text-[12px] font-bold text-[var(--color-ink)]">{viewError}</p>
              ) : cardData ? (
                <IdCardDisplay data={cardData} />
              ) : null}
            </div>
          </section>
        </div>
      ) : null}

      {shareModal ? (
        <div className="fixed inset-0 z-[80] grid place-items-center bg-black/45 p-4 backdrop-blur-sm" onClick={() => setShareModal(null)}>
          <section className="w-full max-w-md rounded-md bg-white p-4 shadow-2xl" onClick={(e) => e.stopPropagation()}>
            <h2 className="text-[13.5px] font-black text-[var(--color-ink)]">Share ID Card</h2>
            <p className="mt-1 text-[12px] text-[var(--color-ink-mute)]">{"Send the public ID card link for " + shareModal.name + " via email"}</p>
            <div className="mt-3">
              <label className="mb-1 block text-[11.5px] font-black text-[var(--color-ink)]">Email Address</label>
              <input type="email" value={shareEmail} onChange={(e) => setShareEmail(e.target.value)} placeholder="Enter email address" className="w-full rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] px-2.5 py-2 text-[12px] font-medium outline-none focus:border-[var(--color-primary)]" />
            </div>
            <p className="mt-3 rounded-md bg-[var(--color-canvas-soft)] px-3 py-2 text-[11px] font-semibold text-[var(--color-ink-mute)]">
              The member opens the link and verifies with their date of birth to view and print the card.
            </p>
            <div className="mt-4 flex justify-end gap-2">
              <button onClick={() => setShareModal(null)} className="rounded-md border border-[var(--color-hairline)] px-3 py-2 text-[11.5px] font-black text-[var(--color-ink)] transition hover:border-[var(--color-primary)] hover:text-[var(--color-primary)]">Cancel</button>
              <button onClick={shareCard} disabled={sending} className="rounded-md bg-gradient-to-r from-[var(--color-primary-deep)] to-[var(--color-primary-deep)] px-4 py-2 text-[11.5px] font-black text-white shadow-[0_8px_18px_rgba(26,107,74,0.28)] transition hover:brightness-105 disabled:opacity-60">
                {sending ? "Sending..." : shareModal && sentCards[shareModal.type + "-" + shareModal.id] ? "Send Again" : "Send Email"}
              </button>
            </div>
          </section>
        </div>
      ) : null}

      <Toaster position="top-center" toastOptions={{ duration: 4000, style: { background: "#333", color: "#fff", fontSize: "14px", fontWeight: "600" } }} />
    </div>
  );
}
