"use client";

import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import {
  BookOpen,
  Calendar,
  Download,
  FileText,
  ChevronDown,
  Loader2,
} from "lucide-react";
import { cn } from "@/lib/utils/cn";
import { PublicPageHeader } from "@/components/shared/public-page";
import { magazineApi } from "@/lib/api/client";

/* ───── Types matching backend MagazineResponse ───── */

interface MagazinePaperResponse {
  paperId: string;
  titleHi: string;
  titleEn: string;
  authorNameHi: string;
  authorNameEn: string;
  paperOrder: number;
  pageStart?: number;
  pageEnd?: number;
  hasPdf: boolean;
}

interface MagazineResponse {
  id: string;
  volume: number;
  issue: number;
  quarter: string;
  coverTitleHi?: string;
  coverTitleEn?: string;
  status: "DRAFT" | "READY" | "PUBLISHED";
  downloadCount: number;
  paperCount: number;
  publishedAt?: string;
  papers: MagazinePaperResponse[];
}

/* ───── Stat Card ───── */

function StatCard({
  label,
  labelHi,
  value,
  sub,
  icon,
}: {
  label: string;
  labelHi: string;
  value: string;
  sub?: string;
  icon: string;
}) {
  return (
    <div className="rounded-2xl border border-gray-100 bg-white p-5 shadow-sm hover:shadow-md transition-shadow">
      <div className="flex items-start justify-between">
        <div>
          <p className="text-sm text-gray-500">{label}</p>
          <p className="text-[10px] text-gray-400">{labelHi}</p>
          <p className="mt-1 text-3xl font-semibold tracking-tight text-gray-900">
            {value}
          </p>
          {sub && <p className="mt-1 text-xs text-emerald-600">{sub}</p>}
        </div>
        <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-blue-50 to-indigo-100 text-lg">
          {icon}
        </div>
      </div>
    </div>
  );
}

/* ───── Badge ───── */

function Badge({
  color,
  children,
}: {
  color: "green" | "indigo" | "amber" | "gray";
  children: React.ReactNode;
}) {
  const colors = {
    green: "bg-emerald-100 text-emerald-700",
    indigo: "bg-indigo-100 text-indigo-700",
    amber: "bg-amber-100 text-amber-700",
    gray: "bg-gray-100 text-gray-600",
  };
  return (
    <span
      className={cn(
        "rounded-full px-2.5 py-1 text-xs font-medium",
        colors[color]
      )}
    >
      {children}
    </span>
  );
}

/* ───── Helpers ───── */

/** Format publishedAt to Hindi-friendly date, fallback to quarter */
function formatDate(publishedAt?: string, quarter?: string): string {
  if (publishedAt) {
    try {
      return new Date(publishedAt).toLocaleDateString("hi-IN", {
        month: "long",
        year: "numeric",
      });
    } catch {
      /* fallback */
    }
  }
  return quarter ?? "";
}

/** Calculate total pages from the last paper's pageEnd */
function calcTotalPages(papers: MagazinePaperResponse[]): number {
  if (papers.length === 0) return 0;
  const sorted = [...papers].sort((a, b) => a.paperOrder - b.paperOrder);
  const lastPage = sorted[sorted.length - 1]?.pageEnd;
  return lastPage ?? papers.length * 14; // estimate ~14 pages/paper if no page info
}

/* ───── Page ───── */

function JournalsList() {
  const [viewIssue, setViewIssue] = useState<string | null>(null);

  const {
    data: journals = [],
    isLoading,
    isError,
  } = useQuery<MagazineResponse[]>({
    queryKey: ["journals"],
    queryFn: async () => {
      const res = await magazineApi.list();
      // Handle both paginated and direct array responses
      return res.data?.content ?? res.data ?? [];
    },
  });

  // Sort: published first (latest first), then upcoming/drafts at the end
  const sorted = [...journals].sort((a, b) => {
    if (a.status === "PUBLISHED" && b.status !== "PUBLISHED") return -1;
    if (a.status !== "PUBLISHED" && b.status === "PUBLISHED") return 1;
    const dateA = a.publishedAt ? new Date(a.publishedAt).getTime() : 0;
    const dateB = b.publishedAt ? new Date(b.publishedAt).getTime() : 0;
    return dateB - dateA;
  });

  const publishedCount = journals.filter(
    (j) => j.status === "PUBLISHED"
  ).length;
  const totalPapers = journals.reduce((sum, j) => sum + j.paperCount, 0);
  const totalDownloads = journals.reduce(
    (sum, j) => sum + j.downloadCount,
    0
  );

  /* ─── Loading ─── */
  if (isLoading) {
    return (
      <div className="flex flex-col items-center justify-center py-20 gap-3">
        <Loader2 className="h-8 w-8 animate-spin text-indigo-500" />
        <p className="text-sm text-gray-400">
          पत्रिकाएँ लोड हो रही हैं... / Loading journals...
        </p>
      </div>
    );
  }

  /* ─── Error ─── */
  if (isError) {
    return (
      <div className="mx-auto max-w-7xl px-4 py-8">
        <div className="rounded-2xl border border-red-200 bg-red-50 p-12 text-center">
          <p className="text-sm text-red-600">
            पत्रिकाएँ लोड करने में त्रुटि / Error loading journals
          </p>
        </div>
      </div>
    );
  }

  /* ─── Empty ─── */
  if (sorted.length === 0) {
    return (
      <div className="mx-auto max-w-7xl px-4 py-8">
        <div className="rounded-2xl border-2 border-dashed border-gray-300 p-16 text-center">
          <BookOpen className="mx-auto h-14 w-14 text-gray-300" />
          <p className="mt-4 text-sm text-gray-400">
            अभी कोई पत्रिका प्रकाशित नहीं हुई / No journals published yet
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="mx-auto max-w-7xl px-4 sm:px-6 py-8">

      {/* ─── Stats Bar ─── */}
      <div className="mb-8 grid grid-cols-2 gap-4 sm:grid-cols-4">
        <StatCard
          label="Total Issues"
          labelHi="कुल अंक"
          value={String(journals.length)}
          icon="📚"
        />
        <StatCard
          label="Published"
          labelHi="प्रकाशित"
          value={String(publishedCount)}
          icon="✅"
        />
        <StatCard
          label="Total Papers"
          labelHi="कुल शोधपत्र"
          value={String(totalPapers)}
          icon="📄"
        />
        <StatCard
          label="Total Downloads"
          labelHi="कुल डाउनलोड"
          value={String(totalDownloads)}
          sub="सभी अंक / All issues"
          icon="⬇️"
        />
      </div>

      {/* ─── Journal Grid ─── */}
      <div className="grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
        {sorted.map((issue) => {
          const isUpcoming = issue.status !== "PUBLISHED";
          const isExpanded = viewIssue === issue.id;
          const totalPages = calcTotalPages(issue.papers);
          const dateLabel = formatDate(issue.publishedAt, issue.quarter);
          const tocPapers = [...issue.papers].sort(
            (a, b) => a.paperOrder - b.paperOrder
          );

          return (
            <div
              key={issue.id}
              className="group cursor-pointer overflow-hidden rounded-2xl border border-gray-100 bg-white transition-all hover:shadow-lg"
              onClick={() => setViewIssue(isExpanded ? null : issue.id)}
            >
              {/* ── Cover ── */}
              <div
                className={cn(
                  "relative px-5 py-6 text-center text-white",
                  isUpcoming
                    ? "bg-gradient-to-br from-indigo-600 to-blue-500"
                    : "bg-gradient-to-br from-slate-700 to-slate-800"
                )}
              >
                {isUpcoming && (
                  <div className="absolute right-3 top-3 rounded-full bg-amber-400 px-2 py-0.5 text-[9px] font-bold uppercase text-amber-900">
                    आगामी / Upcoming
                  </div>
                )}
                <p className="mb-1 text-[10px] uppercase tracking-widest opacity-60">
                  शैक्षणिक प्रेस / Academic Press
                </p>
                <p className="text-xl font-bold">{issue.quarter}</p>
                <p className="mt-0.5 text-xs opacity-75">
                  खंड {issue.volume}, अंक {issue.issue}{" "}
                  <span className="opacity-50">
                    / Vol. {issue.volume}, Issue {issue.issue}
                  </span>
                </p>
                <div className="mt-3 h-px bg-white/20" />
                {(issue.coverTitleHi || issue.coverTitleEn) && (
                  <>
                    <p className="mt-3 text-sm font-medium leading-snug">
                      {issue.coverTitleHi ?? issue.coverTitleEn}
                    </p>
                    {issue.coverTitleEn && issue.coverTitleHi && (
                      <p className="mt-0.5 text-[10px] opacity-60">
                        {issue.coverTitleEn}
                      </p>
                    )}
                  </>
                )}
              </div>

              {/* ── Details ── */}
              <div className="p-4">
                {/* Meta row */}
                <div className="mb-3 flex flex-wrap gap-x-4 gap-y-1 text-[10px] text-gray-500">
                  <span className="flex items-center gap-1">
                    <Calendar className="h-3 w-3" />
                    {dateLabel}
                  </span>
                  <span className="flex items-center gap-1">
                    <FileText className="h-3 w-3" />
                    {issue.paperCount} शोधपत्र
                  </span>
                  {totalPages > 0 && <span>📖 {totalPages} पृष्ठ</span>}
                  {!isUpcoming && (
                    <span className="flex items-center gap-1">
                      <Download className="h-3 w-3" />
                      {issue.downloadCount} डाउनलोड
                    </span>
                  )}
                </div>

                {/* Action row */}
                <div className="flex items-center justify-between">
                  <Badge color={isUpcoming ? "indigo" : "green"}>
                    {isUpcoming ? "आगामी" : "प्रकाशित"}
                  </Badge>

                  {!isUpcoming ? (
                    <div className="flex gap-2">
                      <button
                        className="rounded-lg bg-indigo-50 px-2.5 py-1 text-[10px] font-medium text-indigo-700 transition hover:bg-indigo-100"
                        onClick={async (e) => {
                          e.stopPropagation();
                          try {
                            const res = await magazineApi.downloadIssuePdf(issue.id);
                            const blob = new Blob([res.data], { type: "application/pdf" });
                            const url = URL.createObjectURL(blob);
                            const a = document.createElement("a");
                            a.href = url;
                            a.download = `magazine-vol${issue.volume}-issue${issue.issue}.pdf`;
                            a.click();
                            URL.revokeObjectURL(url);
                          } catch {
                            // silent fallback
                          }
                        }}
                      >
                        <Download className="mr-1 inline h-3 w-3" />
                        PDF
                      </button>
                      <button
                        className="flex items-center gap-1 rounded-lg bg-gray-50 px-2.5 py-1 text-[10px] font-medium text-gray-600 transition hover:bg-gray-100"
                        onClick={(e) => {
                          e.stopPropagation();
                          setViewIssue(isExpanded ? null : issue.id);
                        }}
                      >
                        विषय सूची
                        <ChevronDown
                          className={cn(
                            "h-3 w-3 transition-transform",
                            isExpanded && "rotate-180"
                          )}
                        />
                      </button>
                    </div>
                  ) : (
                    <span className="text-[10px] font-medium text-indigo-500">
                      शीघ्र प्रकाशित होगा...
                    </span>
                  )}
                </div>

                {/* ── Expandable TOC ── */}
                {isExpanded && tocPapers.length > 0 && (
                  <div className="mt-3 border-t border-gray-100 pt-3">
                    <p className="mb-2 text-[10px] font-semibold uppercase tracking-wide text-gray-500">
                      विषय सूची / Table of Contents
                    </p>
                    <div className="space-y-2">
                      {tocPapers.map((paper, pi) => (
                        <div key={paper.paperId} className="flex items-start gap-2">
                          <span className="mt-0.5 w-4 shrink-0 text-[10px] font-mono text-gray-300">
                            {pi + 1}.
                          </span>
                          <div className="min-w-0 flex-1">
                            <p className="text-xs font-medium text-gray-800">
                              {paper.titleHi || paper.titleEn}
                            </p>
                            <p className="text-[10px] text-gray-400">
                              {paper.titleHi ? paper.titleEn : ""}{" "}
                              {paper.titleHi && paper.titleEn ? "· " : ""}
                              {paper.authorNameHi || paper.authorNameEn}
                              {paper.pageStart != null && paper.pageEnd != null ? (
                                <span className="ml-1 text-gray-300">
                                  (pp. {paper.pageStart}–{paper.pageEnd})
                                </span>
                              ) : null}
                            </p>
                          </div>
                          {paper.hasPdf ? (
                            <button
                              className="shrink-0 rounded bg-indigo-50 px-1.5 py-0.5 text-[9px] font-medium text-indigo-600 hover:bg-indigo-100 transition"
                              onClick={async (e) => {
                                e.stopPropagation();
                                try {
                                  const res = await magazineApi.downloadPaperPdf(issue.id, paper.paperOrder);
                                  const blob = new Blob([res.data], { type: "application/pdf" });
                                  const url = URL.createObjectURL(blob);
                                  const a = document.createElement("a");
                                  a.href = url;
                                  a.download = `magazine-vol${issue.volume}-issue${issue.issue}-paper${paper.paperOrder}.pdf`;
                                  a.click();
                                  URL.revokeObjectURL(url);
                                } catch {
                                  // silent fallback
                                }
                              }}
                            >
                              <Download className="mr-0.5 inline h-2.5 w-2.5" />
                              PDF
                            </button>
                          ) : null}
                        </div>
                      ))}
                    </div>
                  </div>
                )}

                {/* No papers message for upcoming */}
                {isExpanded && tocPapers.length === 0 && (
                  <div className="mt-3 border-t border-gray-100 pt-3">
                    <p className="text-center text-[10px] text-gray-400">
                      विषय सूची शीघ्र उपलब्ध होगी / TOC coming soon
                    </p>
                  </div>
                )}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}
/**
 * Published issues, open to everyone.
 *
 * <p>This lived under (dashboard) and so sat behind the login redirect, even
 * though every endpoint it calls — the issue list and both PDF downloads — is
 * public. The navbar offered it to signed-out visitors, who were bounced to a
 * login screen to read work the journal publishes openly. The URL is unchanged:
 * (public) is a route group, not a path segment.
 */
export default function JournalsPage() {
  return (
    <div className="min-h-[60vh] bg-gray-50">
      <PublicPageHeader
        titleHi="प्रकाशित पत्रिकाएँ"
        titleEn="Published Journals"
        breadcrumbs={[
          { label: "होम / Home", href: "/" },
          { label: "प्रकाशित पत्रिकाएँ / Published Journals" },
        ]}
      />
      <JournalsList />
    </div>
  );
}
