"use client";

import { useEffect, useState, useCallback, useMemo } from "react";
import { useSearchParams, useRouter } from "next/navigation";
import { createClient } from "@/lib/supabase/client";
import Card, { CardHeader } from "@/components/ui/Card";
import Button from "@/components/ui/Button";
import Badge from "@/components/ui/Badge";
import Modal from "@/components/ui/Modal";
import Spinner from "@/components/ui/Spinner";
import { Field, Input, Textarea } from "@/components/ui/Input";
import { Select } from "@/components/ui/Select";
import { Table, Td, EmptyRow } from "@/components/ui/Table";
import { useToast } from "@/components/ui/Toast";
import { formatDateTime, formatDate } from "@/lib/format";
import { Award, Gift, Plus, AwardIcon, History, Calendar, CheckCircle, Pencil, Trash2, Search, Users, Trophy } from "lucide-react";

type Volunteer = { id: string; full_name: string; total_merit: number };
type Program = { id: string; title: string; merit_value: number };
type Reward = { id: string; name: string; points_required: number };
type Txn = { id: string; points: number; reason: string | null; created_at: string; who: string; program_title?: string; volunteer_id: string };

// Eligible volunteer row for bulk award (attended the linked program)
type EligibleVolunteer = { id: string; full_name: string; matric_no?: string | null };

function useIsMobileViewport() {
  const [isMobile, setIsMobile] = useState(false);
  useEffect(() => {
    const check = () => setIsMobile(window.innerWidth < 768);
    check();
    window.addEventListener("resize", check);
    return () => window.removeEventListener("resize", check);
  }, []);
  return isMobile;
}

export default function MeritPage() {
  const supabase = createClient();
  const searchParams = useSearchParams();
  const router = useRouter();
  const { notify } = useToast();
  const isMobile = useIsMobileViewport();

  const [loading, setLoading] = useState(true);
  const [userRole, setUserRole] = useState<"admin" | "volunteer">("volunteer");
  const [userId, setUserId] = useState("");
  const [userProfile, setUserProfile] = useState<any>(null);

  // Admin and Volunteer Shared data
  const [volunteers, setVolunteers] = useState<Volunteer[]>([]);
  const [programs, setPrograms] = useState<Program[]>([]);
  const [rewards, setRewards] = useState<Reward[]>([]);
  const [txns, setTxns] = useState<Txn[]>([]);
  const [saving, setSaving] = useState(false);

  // Volunteer specific data
  const [myTxns, setMyTxns] = useState<any[]>([]);
  // Full ranked leaderboard, visible to volunteers in read-only form
  const [leaderboard, setLeaderboard] = useState<Volunteer[]>([]);

  // Modals
  const [pointsOpen, setPointsOpen] = useState(false);
  const [awardOpen, setAwardOpen] = useState(false);
  const [editOpen, setEditOpen] = useState(false);
  const [bulkOpen, setBulkOpen] = useState(false);

  // Forms
  const [pForm, setPForm] = useState({ volunteer_id: "", program_id: "", points: 10, reason: "" });
  const [aForm, setAForm] = useState({ volunteer_id: "", reward_id: "" });
  const [editForm, setEditForm] = useState({ id: "", points: 0, reason: "" });
  const [bulkForm, setBulkForm] = useState({ program_id: "", points: 10, reason: "" });

  // Bulk award: attendance-based eligible volunteers + manual selection
  const [eligibleVolunteers, setEligibleVolunteers] = useState<EligibleVolunteer[]>([]);
  const [selectedVolunteerIds, setSelectedVolunteerIds] = useState<string[]>([]);
  const [eligibleLoading, setEligibleLoading] = useState(false);
  const [bulkSearch, setBulkSearch] = useState("");

  // Filters
  const [search, setSearch] = useState("");
  const [badgeEligibilityFilter, setBadgeEligibilityFilter] = useState<"" | "bronze" | "star" | "silver" | "gold">("");

  const load = useCallback(async () => {
    const { data: userRes } = await supabase.auth.getUser();
    if (!userRes.user) {
      router.push("/login");
      return;
    }
    setUserId(userRes.user.id);

    const { data: profile } = await supabase
      .from("profiles")
      .select("*")
      .eq("id", userRes.user.id)
      .single();

    if (!profile) return;
    setUserRole(profile.role);
    setUserProfile(profile);

    if (profile.role === "admin") {
      const [{ data: v }, { data: p }, { data: r }, { data: t }] = await Promise.all([
        supabase.from("profiles").select("id, full_name, total_merit").eq("role", "volunteer").order("full_name"),
        supabase.from("programs").select("id, title, merit_value").order("start_at", { ascending: false }),
        supabase.from("rewards").select("id, name, points_required").order("points_required"),
        supabase
          .from("merit_transactions")
          .select("id, points, reason, created_at, volunteer_id, programs(title), profiles!volunteer_id(full_name)")
          .order("created_at", { ascending: false }),
      ]);
      setVolunteers((v as Volunteer[]) ?? []);
      setPrograms((p as Program[]) ?? []);
      setRewards((r as Reward[]) ?? []);
      setTxns(
        (t ?? []).map((x: any) => ({
          id: x.id,
          points: x.points,
          reason: x.reason,
          created_at: x.created_at,
          who: x.profiles?.full_name ?? "Unknown",
          program_title: x.programs?.title ?? undefined,
          volunteer_id: x.volunteer_id,
        }))
      );
    } else {
      // Fetch current volunteer's merit transactions + the full leaderboard
      // (read-only ranking of all volunteers) so they can see where they stand.
      const [{ data: t }, { data: lb }] = await Promise.all([
        supabase
          .from("merit_transactions")
          .select("id, points, reason, created_at, programs(title)")
          .eq("volunteer_id", userRes.user.id)
          .order("created_at", { ascending: false }),
        supabase
          .from("profiles")
          .select("id, full_name, total_merit")
          .eq("role", "volunteer")
          .order("total_merit", { ascending: false }),
      ]);

      setMyTxns(t ?? []);
      setLeaderboard((lb as Volunteer[]) ?? []);
    }

    setLoading(false);
  }, [supabase, router]);

  useEffect(() => {
    load();
  }, [load]);

  // When a program is chosen for bulk award: set default points/reason, then
  // load the list of volunteers who actually ATTENDED that program (from the
  // attendance table) — these are the eligible recipients. Admin can still
  // manually check/uncheck individuals from this list before awarding.
  useEffect(() => {
    if (!bulkForm.program_id) {
      setEligibleVolunteers([]);
      setSelectedVolunteerIds([]);
      return;
    }
    const prog = programs.find((p) => p.id === bulkForm.program_id);
    if (prog) {
      setBulkForm((prev) => ({
        ...prev,
        points: prog.merit_value,
        reason: `Completed program: ${prog.title}`,
      }));
    }

    (async () => {
      setEligibleLoading(true);
      const { data: attendanceRows, error } = await supabase
        .from("attendance")
        .select("volunteer_id, profiles!volunteer_id(id, full_name, matric_no)")
        .eq("program_id", bulkForm.program_id);

      if (error) {
        notify(error.message, "error");
        setEligibleVolunteers([]);
        setSelectedVolunteerIds([]);
        setEligibleLoading(false);
        return;
      }

      const eligible: EligibleVolunteer[] = (attendanceRows ?? [])
        .map((row: any) => ({
          id: row.profiles?.id ?? row.volunteer_id,
          full_name: row.profiles?.full_name ?? "Unknown",
          matric_no: row.profiles?.matric_no ?? null,
        }))
        .filter((v) => v.id);

      // De-duplicate just in case, then sort by name
      const seen = new Set<string>();
      const deduped = eligible.filter((v) => {
        if (seen.has(v.id)) return false;
        seen.add(v.id);
        return true;
      });
      deduped.sort((a, b) => a.full_name.localeCompare(b.full_name));

      setEligibleVolunteers(deduped);
      // Default: select everyone who attended. Admin can manually uncheck.
      setSelectedVolunteerIds(deduped.map((v) => v.id));
      setEligibleLoading(false);
    })();
  }, [bulkForm.program_id, programs, supabase, notify]);

  // Check and award badge thresholds: Bronze (50), Star (100), Silver (150), Gold (300)
  async function checkAndAwardBadges(volunteerId: string) {
    const { data: profile } = await supabase
      .from("profiles")
      .select("total_merit")
      .eq("id", volunteerId)
      .single();
    if (!profile) return;
    const currentPoints = profile.total_merit;

    const { data: rewardsData } = await supabase.from("rewards").select("*");
    if (!rewardsData) return;

    const { data: earnedData } = await supabase
      .from("volunteer_rewards")
      .select("reward_id")
      .eq("volunteer_id", volunteerId);
    const earnedIds = new Set((earnedData ?? []).map((r) => r.reward_id));

    for (const reward of rewardsData) {
      if (currentPoints >= reward.points_required && !earnedIds.has(reward.id)) {
        const { error } = await supabase.from("volunteer_rewards").insert({
          volunteer_id: volunteerId,
          reward_id: reward.id,
          earned_at: new Date().toISOString(),
        });
        if (!error) {
          await supabase.from("notifications").insert({
            volunteer_id: volunteerId,
            title: "Badge Unlocked! 🏆",
            message: `Congratulations! You have unlocked the "${reward.name}" badge by reaching ${reward.points_required} Merit Points.`,
            channel: "in_app",
          });
          notify(`New badge unlocked: ${reward.name}!`);
        }
      }
    }
  }

  async function awardPoints(e: React.FormEvent) {
    e.preventDefault();
    if (!pForm.volunteer_id) return notify("Select a volunteer.", "error");
    setSaving(true);
    const { error } = await supabase.from("merit_transactions").insert({
      volunteer_id: pForm.volunteer_id,
      program_id: pForm.program_id || null,
      points: Number(pForm.points),
      reason: pForm.reason || null,
      awarded_by: userId,
    });
    if (error) {
      setSaving(false);
      return notify(error.message, "error");
    }
    await checkAndAwardBadges(pForm.volunteer_id);
    setSaving(false);
    notify("Merit points awarded.");
    setPointsOpen(false);
    setPForm({ volunteer_id: "", program_id: "", points: 10, reason: "" });
    load();
  }

  function toggleVolunteerSelection(id: string) {
    setSelectedVolunteerIds((prev) =>
      prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]
    );
  }

  function selectAllEligible() {
    setSelectedVolunteerIds(eligibleVolunteers.map((v) => v.id));
  }

  function unselectAllEligible() {
    setSelectedVolunteerIds([]);
  }

  // Filtered eligible list for the search box inside the bulk modal
  const filteredEligibleVolunteers = useMemo(() => {
    const q = bulkSearch.trim().toLowerCase();
    if (!q) return eligibleVolunteers;
    return eligibleVolunteers.filter(
      (v) =>
        v.full_name.toLowerCase().includes(q) ||
        (v.matric_no ?? "").toLowerCase().includes(q)
    );
  }, [eligibleVolunteers, bulkSearch]);

  async function bulkAward(e: React.FormEvent) {
    e.preventDefault();
    if (!bulkForm.program_id) return notify("Select a program.", "error");

    const recipients = selectedVolunteerIds;
    if (!recipients.length) {
      return notify("Select at least one volunteer to award.", "error");
    }

    setSaving(true);

    const rows = recipients.map((volunteer_id) => ({
      volunteer_id,
      program_id: bulkForm.program_id,
      points: Number(bulkForm.points),
      reason: bulkForm.reason || "Completed program",
      awarded_by: userId,
    }));

    const { error: insertErr } = await supabase.from("merit_transactions").insert(rows);
    if (insertErr) {
      setSaving(false);
      return notify(insertErr.message, "error");
    }

    for (const vId of recipients) {
      await checkAndAwardBadges(vId);
    }

    setSaving(false);
    notify(`Awarded points to ${recipients.length} volunteer(s).`);
    setBulkOpen(false);
    setBulkForm({ program_id: "", points: 10, reason: "" });
    setEligibleVolunteers([]);
    setSelectedVolunteerIds([]);
    setBulkSearch("");
    load();
  }

  async function saveEditTxn(e: React.FormEvent) {
    e.preventDefault();
    setSaving(true);
    const { error } = await supabase
      .from("merit_transactions")
      .update({
        points: Number(editForm.points),
        reason: editForm.reason || null,
      })
      .eq("id", editForm.id);

    if (error) {
      setSaving(false);
      return notify(error.message, "error");
    }

    const txn = txns.find((t) => t.id === editForm.id);
    if (txn) {
      await checkAndAwardBadges(txn.volunteer_id);
    }

    setSaving(false);
    notify("Transaction updated.");
    setEditOpen(false);
    load();
  }

  async function deleteTxn(id: string) {
    if (!confirm("Are you sure you want to delete this transaction? The volunteer's total merit points will be updated accordingly.")) return;
    const { error } = await supabase.from("merit_transactions").delete().eq("id", id);
    if (error) {
      notify(error.message, "error");
    } else {
      notify("Merit transaction deleted.");
      load();
    }
  }

  async function giveAward(e: React.FormEvent) {
    e.preventDefault();
    if (!aForm.volunteer_id || !aForm.reward_id) return notify("Select a volunteer and a reward.", "error");
    setSaving(true);
    const { error } = await supabase
      .from("volunteer_rewards")
      .insert({ volunteer_id: aForm.volunteer_id, reward_id: aForm.reward_id });
    setSaving(false);
    if (error) return notify(error.message, "error");
    notify("Award given.");
    setAwardOpen(false);
    setAForm({ volunteer_id: "", reward_id: "" });
  }

  // Filter Transactions
  const filteredTxns = useMemo(() => {
    return txns.filter((t) => {
      if (!search.trim()) return true;
      const q = search.toLowerCase();
      const whoName = (t.who || "").toLowerCase();
      const reasonText = (t.reason || "").toLowerCase();
      const progTitle = (t.program_title || "").toLowerCase();
      return whoName.includes(q) || reasonText.includes(q) || progTitle.includes(q);
    });
  }, [txns, search]);

  // Filter Volunteers for Admin Leaderboard
  const filteredVolunteers = useMemo(() => {
    let list = [...volunteers];
    if (badgeEligibilityFilter === "bronze") {
      list = list.filter((v) => v.total_merit >= 50);
    } else if (badgeEligibilityFilter === "star") {
      list = list.filter((v) => v.total_merit >= 100);
    } else if (badgeEligibilityFilter === "silver") {
      list = list.filter((v) => v.total_merit >= 150);
    } else if (badgeEligibilityFilter === "gold") {
      list = list.filter((v) => v.total_merit >= 300);
    }
    return list.sort((a, b) => b.total_merit - a.total_merit);
  }, [volunteers, badgeEligibilityFilter]);

  // Ranked leaderboard for the volunteer view (already sorted by the query,
  // but sort again defensively in case ties/refreshes change ordering).
  const rankedLeaderboard = useMemo(() => {
    return [...leaderboard].sort((a, b) => b.total_merit - a.total_merit);
  }, [leaderboard]);

  const myRank = useMemo(() => {
    const idx = rankedLeaderboard.findIndex((v) => v.id === userId);
    return idx === -1 ? null : idx + 1;
  }, [rankedLeaderboard, userId]);

  if (loading) return <Spinner label="Loading merit data…" />;

  // RENDER ADMIN VIEW
  if (userRole === "admin") {
    return (
      <div className="space-y-6">
        <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <h1 className={`${isMobile ? "text-xl font-bold" : "text-2xl font-extrabold"} text-ink`}>
              Merit &amp; Awards
            </h1>
            <p className="text-sm text-muted">Reward active volunteers with points and achievements.</p>
          </div>
          <div className="flex flex-wrap gap-2">
            <Button variant="secondary" onClick={() => setBulkOpen(true)} className="flex items-center gap-1">
              <Users size={16} /> Bulk Award
            </Button>
            <Button onClick={() => setPointsOpen(true)} className="flex items-center gap-1">
              <Plus size={16} /> Award Points
            </Button>
            <Button variant="secondary" onClick={() => setAwardOpen(true)} className="flex items-center gap-1">
              <Gift size={16} /> Give Award
            </Button>
          </div>
        </div>

        <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
          <Card className="lg:col-span-2">
            <div className="p-5 border-b border-sand-dark/45 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 bg-white rounded-t-card">
              <h3 className="text-sm font-bold text-ink flex items-center gap-2">
                <History size={16} className="text-emerald" /> Recent Merit Transactions
              </h3>

              <div className="relative w-full sm:w-64">
                <Search className="absolute left-2.5 top-2 h-3.5 w-3.5 text-muted" />
                <input
                  type="text"
                  placeholder="Search ledger..."
                  value={search}
                  onChange={(e) => setSearch(e.target.value)}
                  className="w-full rounded-card border border-sand-dark/60 bg-white py-1.5 pl-8 pr-3 text-xs outline-none focus:border-emerald transition-all"
                />
              </div>
            </div>

            <Table headers={["Volunteer", "Points", "Reason", "When", "Actions"]}>
              {filteredTxns.length ? (
                filteredTxns.map((t) => (
                  <tr key={t.id} className="hover:bg-sand/40">
                    <Td className="font-semibold">{t.who}</Td>
                    <Td>
                      <Badge tone={t.points >= 0 ? "emerald" : "red"}>
                        {t.points >= 0 ? "+" : ""}
                        {t.points}
                      </Badge>
                    </Td>
                    <Td className="text-muted">
                      {t.program_title ? (
                        <span>
                          <span className="font-medium text-emerald">{t.program_title}</span>
                          {t.reason ? ` - ${t.reason}` : ""}
                        </span>
                      ) : (
                        t.reason ?? "—"
                      )}
                    </Td>
                    <Td className="text-muted">{formatDateTime(t.created_at)}</Td>
                    <Td>
                      <div className="flex gap-2">
                        <button
                          onClick={() => {
                            setEditForm({ id: t.id, points: t.points, reason: t.reason ?? "" });
                            setEditOpen(true);
                          }}
                          className="rounded-card bg-sand p-1 text-muted hover:text-emerald transition-colors"
                          title="Edit transaction"
                        >
                          <Pencil size={14} />
                        </button>
                        <button
                          onClick={() => deleteTxn(t.id)}
                          className="rounded-card bg-sand p-1 text-muted hover:text-error transition-colors"
                          title="Delete transaction"
                        >
                          <Trash2 size={14} />
                        </button>
                      </div>
                    </Td>
                  </tr>
                ))
              ) : (
                <EmptyRow colSpan={5} message="No merit transactions match your search." />
              )}
            </Table>
          </Card>

          <Card className="h-fit">
            <div className="p-4 border-b border-sand-dark/45 flex justify-between items-center bg-white rounded-t-card">
              <h3 className="text-sm font-bold text-ink">Leaderboard</h3>

              <select
                value={badgeEligibilityFilter}
                onChange={(e) => setBadgeEligibilityFilter(e.target.value as any)}
                className="text-[11px] rounded-card border border-sand-dark/60 bg-white py-1 px-2 outline-none focus:border-emerald font-semibold text-ink"
              >
                <option value="">All volunteers</option>
                <option value="bronze">Bronze (50+ pts)</option>
                <option value="star">Star (100+ pts)</option>
                <option value="silver">Silver (150+ pts)</option>
                <option value="gold">Gold (300+ pts)</option>
              </select>
            </div>

            <ul className="divide-y divide-sand-dark/40 max-h-[350px] overflow-y-auto">
              {filteredVolunteers.map((v, i) => (
                <li key={v.id} className="flex items-center justify-between px-5 py-3 hover:bg-sand/20">
                  <div className="flex items-center gap-3">
                    <span className="flex h-5 w-5 items-center justify-center rounded-full bg-sand text-[10px] font-bold text-emerald">
                      {i + 1}
                    </span>
                    <span className="text-xs font-semibold text-ink">{v.full_name}</span>
                  </div>
                  <Badge tone="emerald">{v.total_merit} pts</Badge>
                </li>
              ))}
              {!filteredVolunteers.length && (
                <li className="px-5 py-10 text-center text-xs text-muted">No volunteers match filter.</li>
              )}
            </ul>
          </Card>
        </div>

        {/* Award points modal */}
        <Modal open={pointsOpen} onClose={() => setPointsOpen(false)} title="Award merit points">
          <form onSubmit={awardPoints} className="space-y-4">
            <Field label="Volunteer">
              <Select value={pForm.volunteer_id} onChange={(e) => setPForm({ ...pForm, volunteer_id: e.target.value })} required>
                <option value="">Select a volunteer…</option>
                {volunteers.map((v) => (
                  <option key={v.id} value={v.id}>
                    {v.full_name} ({v.total_merit} pts)
                  </option>
                ))}
              </Select>
            </Field>
            <Field label="Program (optional)">
              <Select value={pForm.program_id} onChange={(e) => setPForm({ ...pForm, program_id: e.target.value })}>
                <option value="">No specific program</option>
                {programs.map((p) => (
                  <option key={p.id} value={p.id}>
                    {p.title}
                  </option>
                ))}
              </Select>
            </Field>
            <Field label="Points" hint="Use a negative number to deduct points.">
              <Input
                type="number"
                required
                value={pForm.points}
                onChange={(e) => setPForm({ ...pForm, points: Number(e.target.value) })}
              />
            </Field>
            <Field label="Reason">
              <Textarea
                rows={2}
                value={pForm.reason}
                onChange={(e) => setPForm({ ...pForm, reason: e.target.value })}
                placeholder="Completed volunteer tasks successfully"
              />
            </Field>
            <div className="flex justify-end gap-2 pt-2">
              <Button type="button" variant="secondary" onClick={() => setPointsOpen(false)}>
                Cancel
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Saving…" : "Award Points"}
              </Button>
            </div>
          </form>
        </Modal>

        {/* Bulk Program Awarding Modal — attendance-based + manual selection */}
        <Modal open={bulkOpen} onClose={() => setBulkOpen(false)} title="Bulk Award Merit Points" wide>
          <form onSubmit={bulkAward} className="space-y-4">
            <p className="text-sm text-muted -mt-1">
              Select multiple volunteers, set the merit values, and award points to all of them at once.
            </p>

            <Field label="Linked Program">
              <Select value={bulkForm.program_id} onChange={(e) => setBulkForm({ ...bulkForm, program_id: e.target.value })} required>
                <option value="">Select a program…</option>
                {programs.map((p) => (
                  <option key={p.id} value={p.id}>
                    {p.title}
                  </option>
                ))}
              </Select>
            </Field>

            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
              <Field label="Award Points" hint="Defaults to the program's defined merit value.">
                <Input
                  type="number"
                  required
                  value={bulkForm.points}
                  onChange={(e) => setBulkForm({ ...bulkForm, points: Number(e.target.value) })}
                />
              </Field>
              <Field label="Reason / Reflection">
                <Input
                  value={bulkForm.reason}
                  onChange={(e) => setBulkForm({ ...bulkForm, reason: e.target.value })}
                  placeholder="Completed program"
                />
              </Field>
            </div>

            <hr className="border-sand-dark/30" />

            <div className="flex items-center justify-between">
              <h4 className="text-sm font-bold text-ink">
                Select Volunteers ({selectedVolunteerIds.length} selected)
              </h4>
              <div className="flex gap-3">
                <button
                  type="button"
                  onClick={selectAllEligible}
                  disabled={!eligibleVolunteers.length}
                  className="text-xs font-bold text-emerald hover:underline disabled:opacity-40 disabled:hover:no-underline"
                >
                  Select All
                </button>
                <button
                  type="button"
                  onClick={unselectAllEligible}
                  disabled={!selectedVolunteerIds.length}
                  className="text-xs font-bold text-muted hover:underline disabled:opacity-40 disabled:hover:no-underline"
                >
                  Unselect All
                </button>
              </div>
            </div>

            <div className="relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted" />
              <input
                type="text"
                placeholder="Search volunteers by name…"
                value={bulkSearch}
                onChange={(e) => setBulkSearch(e.target.value)}
                className="w-full rounded-card border-2 border-emerald/60 bg-white py-2.5 pl-10 pr-3 text-sm outline-none focus:border-emerald transition-all"
              />
            </div>

            <div className="max-h-72 overflow-y-auto rounded-card border border-sand-dark/60 bg-white divide-y divide-sand-dark/30">
              {!bulkForm.program_id ? (
                <p className="px-4 py-10 text-center text-sm text-muted">
                  Select a program above to see who attended.
                </p>
              ) : eligibleLoading ? (
                <div className="py-8">
                  <Spinner label="Loading attendees…" />
                </div>
              ) : filteredEligibleVolunteers.length ? (
                filteredEligibleVolunteers.map((v) => {
                  const checked = selectedVolunteerIds.includes(v.id);
                  return (
                    <label
                      key={v.id}
                      className="flex items-center justify-between px-4 py-3 cursor-pointer hover:bg-sand/30 transition-colors"
                    >
                      <div>
                        <p className="text-sm font-semibold text-ink">{v.full_name}</p>
                        {v.matric_no && <p className="text-xs text-muted">{v.matric_no}</p>}
                      </div>
                      <input
                        type="checkbox"
                        checked={checked}
                        onChange={() => toggleVolunteerSelection(v.id)}
                        className="h-5 w-5 rounded border-sand-dark text-emerald focus:ring-emerald/30"
                      />
                    </label>
                  );
                })
              ) : (
                <p className="px-4 py-10 text-center text-sm text-muted">
                  No volunteers checked in to attendance for this program yet. Registered volunteers who
                  did not check in via the attendance QR are not shown here — use the per-volunteer "Award
                  Points" action instead if you need to award someone who attended but wasn't scanned in.
                </p>
              )}
            </div>

            <div className="flex justify-end gap-2 pt-2">
              <Button type="button" variant="secondary" onClick={() => setBulkOpen(false)}>
                Cancel
              </Button>
              <Button type="submit" disabled={saving || !selectedVolunteerIds.length || !bulkForm.program_id}>
                {saving ? "Awarding…" : `Give Award to ${selectedVolunteerIds.length} Volunteers`}
              </Button>
            </div>
          </form>
        </Modal>

        {/* Edit points modal */}
        <Modal open={editOpen} onClose={() => setEditOpen(false)} title="Edit Merit Transaction">
          <form onSubmit={saveEditTxn} className="space-y-4">
            <Field label="Points">
              <Input
                type="number"
                required
                value={editForm.points}
                onChange={(e) => setEditForm({ ...editForm, points: Number(e.target.value) })}
              />
            </Field>
            <Field label="Reason">
              <Textarea
                rows={2}
                value={editForm.reason}
                onChange={(e) => setEditForm({ ...editForm, reason: e.target.value })}
                placeholder="Completed volunteer tasks successfully"
              />
            </Field>
            <div className="flex justify-end gap-2 pt-2">
              <Button type="button" variant="secondary" onClick={() => setEditOpen(false)}>
                Cancel
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Saving…" : "Save Changes"}
              </Button>
            </div>
          </form>
        </Modal>

        {/* Give award modal */}
        <Modal open={awardOpen} onClose={() => setAwardOpen(false)} title="Give an award">
          <form onSubmit={giveAward} className="space-y-4">
            <Field label="Volunteer">
              <Select value={aForm.volunteer_id} onChange={(e) => setAForm({ ...aForm, volunteer_id: e.target.value })}>
                <option value="">Select a volunteer…</option>
                {volunteers.map((v) => (
                  <option key={v.id} value={v.id}>
                    {v.full_name}
                  </option>
                ))}
              </Select>
            </Field>
            <Field label="Award">
              {rewards.length ? (
                <Select value={aForm.reward_id} onChange={(e) => setAForm({ ...aForm, reward_id: e.target.value })}>
                  <option value="">Select an award…</option>
                  {rewards.map((r) => (
                    <option key={r.id} value={r.id}>
                      {r.name} ({r.points_required} pts)
                    </option>
                  ))}
                </Select>
              ) : (
                <p className="flex items-center gap-2 text-sm text-muted">
                  <Award size={15} /> No rewards defined. Add rows to the rewards table first.
                </p>
              )}
            </Field>
            <div className="flex justify-end gap-2 pt-2">
              <Button type="button" variant="secondary" onClick={() => setAwardOpen(false)}>
                Cancel
              </Button>
              <Button type="submit" disabled={saving || !rewards.length}>
                {saving ? "Saving…" : "Give award"}
              </Button>
            </div>
          </form>
        </Modal>
      </div>
    );
  }

  // RENDER VOLUNTEER (STUDENT) VIEW
  return (
    <div className="space-y-6">
      <div>
        <h1 className={`${isMobile ? "text-xl font-bold" : "text-2xl font-extrabold"} text-ink`}>
          Merit Points
        </h1>
        <p className="text-sm text-muted">Track your volunteer merit points and rewards earned.</p>
      </div>

      <div className={`grid grid-cols-1 gap-6 ${isMobile ? "" : "lg:grid-cols-3"}`}>
        {/* Merit Summary Card */}
        <div className="rounded-card bg-gradient-to-br from-emerald to-emerald-dark p-6 text-white shadow-card relative overflow-hidden flex flex-col justify-between h-48 lg:col-span-1">
          <div className="absolute right-0 bottom-0 translate-x-3 translate-y-3 opacity-15">
            <AwardIcon size={120} />
          </div>
          <div>
            <p className="text-xs font-semibold text-emerald-light/80 uppercase tracking-wider">Your Balance</p>
            <h2 className="mt-2 text-5xl font-extrabold leading-none">{userProfile?.total_merit}</h2>
            <p className="mt-1 text-sm text-emerald-light/95">
              Merit Points (MP){myRank && <> · Rank #{myRank}</>}
            </p>
          </div>
          <button
            onClick={() => router.push("/achievement")}
            className="flex items-center justify-center gap-1.5 w-full rounded-card bg-white py-2 text-xs font-bold text-emerald hover:bg-emerald-light transition-colors mt-3"
          >
            <Gift size={14} /> View Achievement Badges
          </button>
        </div>

        {/* Leaderboard — read-only ranking, current volunteer's row highlighted */}
        <Card className="lg:col-span-1 h-fit">
          <div className="p-4 border-b border-sand-dark/45 flex items-center gap-2 bg-white rounded-t-card">
            <Trophy size={16} className="text-emerald" />
            <h3 className="text-sm font-bold text-ink">Leaderboard</h3>
          </div>
          <ul className="divide-y divide-sand-dark/40 max-h-[280px] overflow-y-auto">
            {rankedLeaderboard.length ? (
              rankedLeaderboard.map((v, i) => {
                const isMe = v.id === userId;
                return (
                  <li
                    key={v.id}
                    className={`flex items-center justify-between px-5 py-3 ${
                      isMe ? "bg-emerald-light/40" : "hover:bg-sand/20"
                    }`}
                  >
                    <div className="flex items-center gap-3">
                      <span
                        className={`flex h-5 w-5 items-center justify-center rounded-full text-[10px] font-bold ${
                          isMe ? "bg-emerald text-white" : "bg-sand text-emerald"
                        }`}
                      >
                        {i + 1}
                      </span>
                      <span className={`text-xs font-semibold ${isMe ? "text-emerald" : "text-ink"}`}>
                        {v.full_name}
                        {isMe && " (You)"}
                      </span>
                    </div>
                    <Badge tone="emerald">{v.total_merit} pts</Badge>
                  </li>
                );
              })
            ) : (
              <li className="px-5 py-10 text-center text-xs text-muted">No volunteers yet.</li>
            )}
          </ul>
        </Card>

        {/* History Transactions */}
        <Card className="lg:col-span-1">
          <CardHeader title="Merit point ledger" />
          {isMobile ? (
            <ul className="divide-y divide-sand-dark/40">
              {myTxns.length > 0 ? (
                myTxns.map((t) => (
                  <li key={t.id} className="p-4 flex items-center justify-between gap-4">
                    <div className="space-y-0.5">
                      <h4 className="text-xs font-bold text-ink truncate max-w-[200px]">
                        {t.programs?.title ?? t.reason ?? "Merit Points Awarded"}
                      </h4>
                      <p className="text-[10px] text-muted">Awarded on {formatDate(t.created_at)}</p>
                    </div>
                    <span className={`text-sm font-extrabold ${t.points >= 0 ? "text-emerald" : "text-error"}`}>
                      {t.points >= 0 ? "+" : ""}
                      {t.points} MP
                    </span>
                  </li>
                ))
              ) : (
                <li className="p-10 text-center text-xs text-muted">No points earned yet.</li>
              )}
            </ul>
          ) : (
            <Table headers={["Program / Reason", "Points", "Awarded Date"]}>
              {myTxns.length > 0 ? (
                myTxns.map((t) => (
                  <tr key={t.id} className="hover:bg-sand/40">
                    <Td className="font-semibold text-ink">
                      {t.programs?.title ?? t.reason ?? "Merit Points Awarded"}
                    </Td>
                    <Td>
                      <Badge tone={t.points >= 0 ? "emerald" : "red"}>
                        {t.points >= 0 ? "+" : ""}
                        {t.points} MP
                      </Badge>
                    </Td>
                    <Td className="text-muted">{formatDateTime(t.created_at)}</Td>
                  </tr>
                ))
              ) : (
                <EmptyRow colSpan={3} message="No merit points recorded yet." />
              )}
            </Table>
          )}
        </Card>
      </div>
    </div>
  );
}