"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 Spinner from "@/components/ui/Spinner";
import { Table, Td, EmptyRow } from "@/components/ui/Table";
import { useToast } from "@/components/ui/Toast";
import { formatDate } from "@/lib/format";
import { Check, X, ClipboardCheck, Clock, CheckCircle2, XCircle, Search, Download } from "lucide-react";

type Application = {
  id: string;
  applied_at: string;
  status: "pending" | "approved" | "rejected";
  volunteer_id: string;
  volunteer_name?: string;
  volunteer_email?: string;
  program_id: string;
  program_title: string;
  program_venue: string | null;
  program_start_at: string;
  program_merit: number;
};

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 ApplicationsPage() {
  const supabase = createClient();
  const searchParams = useSearchParams();
  const router = useRouter();
  const { notify } = useToast();
  const isViewportMobile = useIsMobileViewport();
  const isPreviewMobile = searchParams.get("preview") === "mobile";
  const isMobile = isViewportMobile || isPreviewMobile;

  const [loading, setLoading] = useState(true);
  const [userRole, setUserRole] = useState<"admin" | "volunteer">("volunteer");
  const [userId, setUserId] = useState("");
  const [apps, setApps] = useState<Application[]>([]);
  const [tab, setTab] = useState<"all" | "pending" | "approved" | "rejected">("all");
  const [search, setSearch] = useState("");

  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("role")
      .eq("id", userRes.user.id)
      .single();

    const role = profile?.role || "volunteer";
    setUserRole(role);

    if (role === "admin") {
      // Fetch all applications for admin review
      const { data } = await supabase
        .from("applications")
        .select(`
          id,
          status,
          applied_at,
          volunteer_id,
          profiles!volunteer_id(full_name, email),
          programs(id, title, venue, start_at, merit_value)
        `)
        .order("applied_at", { ascending: false });

      const mappedApps = (data ?? []).map((row: any) => ({
        id: row.id,
        applied_at: row.applied_at,
        status: row.status,
        volunteer_id: row.volunteer_id,
        volunteer_name: row.profiles?.full_name ?? "Unknown Volunteer",
        volunteer_email: row.profiles?.email ?? "",
        program_id: row.programs?.id ?? "",
        program_title: row.programs?.title ?? "Unknown Program",
        program_venue: row.programs?.venue ?? "",
        program_start_at: row.programs?.start_at ?? "",
        program_merit: row.programs?.merit_value ?? 0,
      }));
      setApps(mappedApps);
    } else {
      // Fetch student's own applications
      const { data } = await supabase
        .from("applications")
        .select(`
          id,
          status,
          applied_at,
          volunteer_id,
          programs(id, title, venue, start_at, merit_value)
        `)
        .eq("volunteer_id", userRes.user.id)
        .order("applied_at", { ascending: false });

      const mappedApps = (data ?? []).map((row: any) => ({
        id: row.id,
        applied_at: row.applied_at,
        status: row.status,
        volunteer_id: row.volunteer_id,
        program_id: row.programs?.id ?? "",
        program_title: row.programs?.title ?? "Unknown Program",
        program_venue: row.programs?.venue ?? "",
        program_start_at: row.programs?.start_at ?? "",
        program_merit: row.programs?.merit_value ?? 0,
      }));
      setApps(mappedApps);
    }

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

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

  // Admin decision handler
  async function review(id: string, status: "approved" | "rejected") {
    const { error } = await supabase
      .from("applications")
      .update({
        status,
        reviewed_by: userId,
        reviewed_at: new Date().toISOString(),
      })
      .eq("id", id);

    if (error) {
      notify(error.message, "error");
    } else {
      notify(status === "approved" ? "Application approved!" : "Application rejected.");

      // Add a notification entry for the student
      const app = apps.find(a => a.id === id);
      if (app) {
        await supabase.from("notifications").insert({
          volunteer_id: app.volunteer_id,
          program_id: app.program_id,
          title: status === "approved" ? "Application Accepted" : "Application Rejected",
          message: `Your application for "${app.program_title}" has been ${status === "approved" ? "approved" : "rejected"}.`,
          channel: "in_app"
        });
      }

      load();
    }
  }

  // Filter list
  const filtered = useMemo(() => {
    return apps.filter((a) => {
      // Tab filter
      if (tab === "pending" && a.status !== "pending") return false;
      if (tab === "approved" && a.status !== "approved") return false;
      if (tab === "rejected" && a.status !== "rejected") return false;

      // Local search filter
      if (search.trim()) {
        const q = search.toLowerCase();
        const vName = (a.volunteer_name || "").toLowerCase();
        const vEmail = (a.volunteer_email || "").toLowerCase();
        const pTitle = (a.program_title || "").toLowerCase();
        const pVenue = (a.program_venue || "").toLowerCase();
        return (
          vName.includes(q) ||
          vEmail.includes(q) ||
          pTitle.includes(q) ||
          pVenue.includes(q)
        );
      }

      return true;
    });
  }, [apps, tab, search]);

  // PDF Export for Admins
  async function handleExportPDF() {
    const { jsPDF } = await import("jspdf");
    const doc = new jsPDF({ orientation: "landscape", unit: "pt", format: "a4" });
    const W = doc.internal.pageSize.getWidth();
    const H = doc.internal.pageSize.getHeight();

    const emerald: [number, number, number] = [15, 110, 86];
    const ink: [number, number, number] = [26, 26, 26];
    const border: [number, number, number] = [220, 215, 200];

    // Banner
    doc.setFillColor(...emerald);
    doc.rect(0, 0, W, 80, "F");

    doc.setFont("helvetica", "bold");
    doc.setFontSize(22);
    doc.setTextColor(255, 255, 255);
    doc.text("Volunteer Application Report", 40, 48);

    doc.setFont("helvetica", "normal");
    doc.setFontSize(10);
    doc.text(`Status filter: ${tab.toUpperCase()} | Generated: ${new Date().toLocaleDateString()}`, W - 40, 48, { align: "right" });

    // Table Headers
    const startX = 40;
    const startY = 120;
    const columns = [
      { name: "Volunteer Name", w: 180 },
      { name: "Email Address", w: 180 },
      { name: "Program Title", w: 220 },
      { name: "Applied Date", w: 100 },
      { name: "Status", w: 80 }
    ];

    // Header background
    doc.setFillColor(245, 243, 235);
    doc.rect(startX, startY - 15, W - 80, 22, "F");

    doc.setFont("helvetica", "bold");
    doc.setFontSize(10);
    doc.setTextColor(...ink);

    let curX = startX;
    columns.forEach(col => {
      doc.text(col.name, curX, startY);
      curX += col.w;
    });

    doc.setDrawColor(...emerald);
    doc.setLineWidth(1.5);
    doc.line(startX, startY + 10, W - 40, startY + 10);

    let y = startY + 30;
    filtered.forEach((app, idx) => {
      if (y > H - 50) {
        doc.addPage();
        doc.setFillColor(...emerald);
        doc.rect(0, 0, W, 50, "F");
        doc.setFont("helvetica", "bold");
        doc.setFontSize(14);
        doc.setTextColor(255, 255, 255);
        doc.text("Volunteer Application Report (Continued)", 40, 30);

        y = 90;
        doc.setFillColor(245, 243, 235);
        doc.rect(startX, y - 15, W - 80, 22, "F");
        doc.setFont("helvetica", "bold");
        doc.setFontSize(10);
        doc.setTextColor(...ink);

        let tempX = startX;
        columns.forEach(col => {
          doc.text(col.name, tempX, y);
          tempX += col.w;
        });

        doc.setDrawColor(...emerald);
        doc.setLineWidth(1.5);
        doc.line(startX, y + 10, W - 40, y + 10);
        y += 30;
      }

      if (idx % 2 === 1) {
        doc.setFillColor(250, 249, 245);
        doc.rect(startX, y - 12, W - 80, 18, "F");
      }

      doc.setFont("helvetica", "normal");
      doc.setFontSize(9);
      doc.setTextColor(...ink);

      doc.text(app.volunteer_name || "Unknown", startX, y);
      doc.text(app.volunteer_email || "", startX + 180, y);
      
      let progTitle = app.program_title || "Unknown Program";
      if (progTitle.length > 40) progTitle = progTitle.substring(0, 37) + "...";
      doc.text(progTitle, startX + 360, y);

      doc.text(formatDate(app.applied_at), startX + 580, y);

      if (app.status === "approved") {
        doc.setTextColor(15, 110, 86);
        doc.setFont("helvetica", "bold");
      } else if (app.status === "rejected") {
        doc.setTextColor(220, 38, 38);
        doc.setFont("helvetica", "bold");
      } else {
        doc.setTextColor(217, 119, 6);
        doc.setFont("helvetica", "bold");
      }
      doc.text(app.status.toUpperCase(), startX + 680, y);

      doc.setDrawColor(...border);
      doc.setLineWidth(0.5);
      doc.line(startX, y + 8, W - 40, y + 8);

      y += 20;
    });

    doc.save(`volunteer_applications_report_${tab}.pdf`);
  }

  // Excel (CSV) Export for Admins
  function handleExportExcel() {
    const headers = ["Volunteer Name", "Email Address", "Program Title", "Applied Date", "Status"];
    const rows = filtered.map((app) => [
      app.volunteer_name || "Unknown",
      app.volunteer_email || "",
      app.program_title || "Unknown Program",
      formatDate(app.applied_at),
      app.status.toUpperCase(),
    ]);

    // Construct CSV content with BOM for UTF-8 compatibility in Excel
    const csvContent = "\uFEFF" + [
      headers.join(","),
      ...rows.map((row) => row.map((val) => `"${val.replace(/"/g, '""')}"`).join(",")),
    ].join("\n");

    const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.setAttribute("href", url);
    link.setAttribute("download", `volunteer_applications_${tab}_${new Date().toISOString().slice(0,10)}.csv`);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }

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

  // RENDER ADMIN APPLICATION REVIEW
  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`}>
              Manage Applications
            </h1>
            <p className="text-sm text-muted">Review, approve, and reject volunteer program registrations.</p>
          </div>
          <div className="flex flex-wrap gap-2 sm:self-end self-start">
            <Button variant="secondary" onClick={handleExportExcel} className="flex items-center gap-1.5">
              <Download size={15} /> Export Excel (CSV)
            </Button>
            <Button onClick={handleExportPDF} className="flex items-center gap-1.5">
              <Download size={15} /> Export PDF Report
            </Button>
          </div>
        </div>

        {/* Local Search and Tab Selector */}
        <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
          <div className="relative w-full max-w-md">
            <Search className="absolute left-3 top-2.5 h-4 w-4 text-muted" />
            <input
              type="text"
              placeholder="Search by student name, email, program..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="w-full rounded-card border border-sand-dark/60 bg-white py-2 pl-9 pr-4 text-sm outline-none focus:border-emerald transition-all"
            />
          </div>

          <div className="flex border-b border-sand-dark/45 self-start md:self-auto overflow-x-auto max-w-full">
            {(["all", "pending", "approved", "rejected"] as const).map((t) => (
              <button
                key={t}
                onClick={() => setTab(t)}
                className={`border-b-2 px-4 py-2 text-xs font-bold uppercase tracking-wider transition-all whitespace-nowrap ${
                  tab === t
                    ? "border-emerald text-emerald font-extrabold"
                    : "border-transparent text-muted hover:text-ink"
                }`}
              >
                {t} ({apps.filter(a => t === "all" ? true : a.status === t).length})
              </button>
            ))}
          </div>
        </div>

        {isMobile ? (
          <div className="space-y-3">
            {filtered.length > 0 ? (
              filtered.map((a) => (
                <div key={a.id} className="rounded-card border border-sand-dark/60 bg-white p-4 shadow-card">
                  <div className="flex justify-between items-start">
                    <div>
                      <h3 className="text-sm font-bold text-ink">{a.volunteer_name}</h3>
                      <p className="text-xs text-muted">{a.volunteer_email}</p>
                      <div className="mt-2 space-y-0.5 text-xs text-ink font-medium">
                        <p>Program: <span className="font-bold text-emerald">{a.program_title}</span></p>
                        <p className="text-[11px] text-muted">Applied: {formatDate(a.applied_at)}</p>
                      </div>
                    </div>
                    <Badge tone={a.status === "approved" ? "emerald" : a.status === "rejected" ? "red" : "amber"}>
                      {a.status}
                    </Badge>
                  </div>

                  {a.status === "pending" && (
                    <div className="mt-3 flex gap-2 border-t border-sand-light pt-2.5">
                      <button
                        onClick={() => review(a.id, "approved")}
                        className="flex flex-1 items-center justify-center gap-1 rounded-card bg-emerald py-2 text-xs font-bold text-white hover:bg-emerald-dark"
                      >
                        <Check size={14} /> Approve
                      </button>
                      <button
                        onClick={() => review(a.id, "rejected")}
                        className="flex flex-1 items-center justify-center gap-1 rounded-card bg-white border border-error/30 py-2 text-xs font-bold text-error hover:bg-error/10"
                      >
                        <X size={14} /> Reject
                      </button>
                    </div>
                  )}
                </div>
              ))
            ) : (
              <p className="text-center py-10 text-xs text-muted">No applications found.</p>
            )}
          </div>
        ) : (
          <Card>
            <Table headers={["Volunteer", "Program", "Applied Date", "Status", "Actions"]}>
              {filtered.length ? (
                filtered.map((a) => (
                  <tr key={a.id} className="hover:bg-sand/40">
                    <Td>
                      <div>
                        <p className="font-semibold text-ink">{a.volunteer_name}</p>
                        <p className="text-xs text-muted">{a.volunteer_email}</p>
                      </div>
                    </Td>
                    <Td className="font-semibold text-emerald">{a.program_title}</Td>
                    <Td>{formatDate(a.applied_at)}</Td>
                    <Td>
                      <Badge tone={a.status === "approved" ? "emerald" : a.status === "rejected" ? "red" : "amber"}>
                        {a.status}
                      </Badge>
                    </Td>
                    <Td>
                      {a.status === "pending" ? (
                        <div className="flex gap-2">
                          <Button size="sm" onClick={() => review(a.id, "approved")}>
                            <Check size={14} /> Approve
                          </Button>
                          <Button size="sm" variant="danger" onClick={() => review(a.id, "rejected")}>
                            <X size={14} /> Reject
                          </Button>
                        </div>
                      ) : (
                        <span className="text-xs text-muted">—</span>
                      )}
                    </Td>
                  </tr>
                ))
              ) : (
                <EmptyRow colSpan={5} message="No applications found." />
              )}
            </Table>
          </Card>
        )}
      </div>
    );
  }

  // RENDER VOLUNTEER (STUDENT) APPLICATIONS VIEW
  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`}>
            My Applications
          </h1>
          <p className="text-sm text-muted">Track the status of your volunteer program registrations.</p>
        </div>
        
        <div className="relative w-full max-w-sm">
          <Search className="absolute left-3 top-2.5 h-4 w-4 text-muted" />
          <input
            type="text"
            placeholder="Search by program, venue..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="w-full rounded-card border border-sand-dark/60 bg-white py-2 pl-9 pr-4 text-sm outline-none focus:border-emerald transition-all"
          />
        </div>
      </div>

      {/* Tabs */}
      <div className="flex border-b border-sand-dark/45 bg-sand/20 rounded-t-card overflow-x-auto max-w-full">
        {(["all", "pending", "approved", "rejected"] as const).map((t) => (
          <button
            key={t}
            onClick={() => setTab(t)}
            className={`border-b-2 px-4 py-2.5 text-xs font-bold uppercase tracking-wider transition-all whitespace-nowrap ${
              tab === t
                ? "border-emerald text-emerald font-extrabold"
                : "border-transparent text-muted hover:text-ink"
            }`}
          >
            {t === "approved" ? "accepted" : t} ({apps.filter((a) => t === "all" ? true : a.status === t).length})
          </button>
        ))}
      </div>

      <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
        {filtered.length > 0 ? (
          filtered.map((a) => (
            <div
              key={a.id}
              className="rounded-card border border-sand-dark/60 bg-white p-5 shadow-card hover:shadow-cardHover transition-all flex flex-col justify-between"
            >
              <div>
                <div className="flex justify-between items-start gap-2 mb-2">
                  <h3 className="text-sm font-bold text-ink leading-tight line-clamp-1">{a.program_title}</h3>
                  <span
                    className={`rounded-full px-2.5 py-0.5 text-[10px] font-bold ${
                      a.status === "approved"
                        ? "bg-emerald-light text-emerald"
                        : a.status === "rejected"
                        ? "bg-red-50 text-error"
                        : "bg-amber-50 text-warning"
                    }`}
                  >
                    {a.status === "approved" ? "Accepted" : a.status === "rejected" ? "Rejected" : "Pending"}
                  </span>
                </div>
                <div className="space-y-1 mt-3 text-xs text-muted">
                  <p>📍 {a.program_venue ?? "Online"}</p>
                  <p>📅 {formatDate(a.program_start_at)}</p>
                  <p className="font-semibold text-emerald">🎖️ {a.program_merit} merit points</p>
                </div>
              </div>
              <div className="mt-4 border-t border-sand-light pt-3 flex justify-between items-center text-[10px] text-muted">
                <span>Applied: {formatDate(a.applied_at)}</span>
                <span className="flex items-center gap-1">
                  {a.status === "pending" && <Clock size={12} className="text-warning" />}
                  {a.status === "approved" && <CheckCircle2 size={12} className="text-emerald" />}
                  {a.status === "rejected" && <XCircle size={12} className="text-error" />}
                  {a.status === "approved" ? "Good to go!" : a.status === "rejected" ? "Try another program" : "Under review"}
                </span>
              </div>
            </div>
          ))
        ) : (
          <div className="col-span-full py-16 text-center text-sm text-muted">
            No applications found matching this status.
          </div>
        )}
      </div>
    </div>
  );
}
