/**
 * PdfReadingView — full-screen PDF reading powered by PDF.js.
 */

import { lazy, Suspense, useCallback, useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18n-lite";
import { useAnnotations } from "@/context/AnnotationsContext";
import { useBookmarkRailLayout } from "../../hooks/useBookmarkRailLayout";
import { usePdfHighlights } from "../../hooks/usePdfHighlights";
import { usePdfReader } from "../../hooks/usePdfReader";
import { usePdfSelection } from "../../hooks/usePdfSelection";
import { useReadingSettings } from "../../hooks/useReadingSettings";
import { booksApi } from "../../api/books";
import type { EBookDetail } from "../../types/book";
import type { EpubTocItem } from "./TableOfContents";
import { parsePageHref } from "../../utils/pdfAnchor";
import { fallbackPdfPageToc } from "../../utils/pdfToc";
import { SelectionPopover } from "./SelectionPopover";
import { BookMarkersPanel } from "./BookMarkersPanel";
import { BookmarkReaderRail } from "./BookmarkReaderRail";
import { ResumeReadingButton } from "./ResumeReadingButton";
import { PdfLimitationsNotice } from "./PdfLimitationsNotice";
import { PdfViewer } from "./PdfViewer";
import type { MarkerEntry } from "@/types";

const ReaderToolbar = lazy(() => import("./ReaderToolbar"));
const TableOfContents = lazy(() => import("./TableOfContents"));
const ReadingSettingsPanel = lazy(() => import("./ReadingSettingsPanel"));

interface PdfReadingViewProps {
  book: EBookDetail;
  bookId: number;
  initialAnchor?: string;
}

export function PdfReadingView({ book, bookId, initialAnchor }: PdfReadingViewProps) {
  const { t } = useTranslation();
  const navigate = useNavigate();

  const [tocOpen, setTocOpen] = useState(false);
  const [settingsOpen, setSettingsOpen] = useState(false);
  const [markersOpen, setMarkersOpen] = useState(false);
  const [tocItems, setTocItems] = useState<EpubTocItem[]>([]);

  const { settings, updateSettings, flushSettings } = useReadingSettings();

  const {
    pdfDocument,
    currentPage,
    pageCount,
    scale,
    setScale,
    chapterTitle,
    progress,
    isLoading,
    error,
    isBookmarkPeekActive,
    readingAnchor,
    pageWrapRef,
    goToPage,
    goToNextPage,
    goToPrevPage,
    beginBookmarkPeek,
    resumeReadingAnchor,
    goToAnchor,
  } = usePdfReader(bookId, book.page_count, initialAnchor);

  const { pendingSelection, clearSelection } = usePdfSelection(
    pageWrapRef,
    currentPage,
    chapterTitle,
  );

  const { markers } = useAnnotations();
  const bookMarkers = useMemo(
    () => markers.filter((m) => m.ebook_id === bookId),
    [markers, bookId],
  );

  const pdfHighlights = usePdfHighlights(bookId, currentPage);
  const railItems = useBookmarkRailLayout(bookMarkers);

  useEffect(() => {
    void booksApi
      .getToc(bookId)
      .then((res) => {
        const items = res.chapters.map((ch) => ({
          label: ch.title,
          href: ch.href || `pdf:page:${ch.index + 1}`,
        }));
        setTocItems(
          items.length > 0
            ? items
            : fallbackPdfPageToc(pageCount, (p) => t("reader.pdfPageLabel", { page: String(p) })),
        );
      })
      .catch(() =>
        setTocItems(fallbackPdfPageToc(pageCount, (p) => t("reader.pdfPageLabel", { page: String(p) }))),
      );
  }, [bookId, pageCount, t]);

  useEffect(() => {
    const root = document.documentElement;
    if (settings.orientation_lock !== "auto") {
      root.style.setProperty(
        "--reader-orientation",
        settings.orientation_lock === "portrait" ? "portrait" : "landscape",
      );
    } else {
      root.style.removeProperty("--reader-orientation");
    }
  }, [settings.orientation_lock]);

  const handleTocNavigate = useCallback(
    (href: string) => {
      const page = parsePageHref(href);
      if (page) goToPage(page);
      else goToAnchor(href);
    },
    [goToAnchor, goToPage],
  );

  const handleGoToMarker = useCallback(
    (marker: MarkerEntry) => {
      beginBookmarkPeek(marker.epub_cfi);
      setMarkersOpen(false);
    },
    [beginBookmarkPeek],
  );

  const progressForToolbar = useMemo(() => {
    if (!progress) return progress;
    const pct = pageCount > 0 ? Math.round((currentPage / pageCount) * 100) : 0;
    return {
      ...progress,
      percentage: pct,
      current_position: pct,
      current_chapter: currentPage,
    };
  }, [progress, currentPage, pageCount]);

  if (isLoading) {
    return (
      <div className="reader-loading">
        <div className="spinner" />
        <p>{t("reader.loading")}</p>
      </div>
    );
  }

  if (error || !pdfDocument) {
    const message =
      error === "PDF_PASSWORD" ? t("reader.pdfPassword") : (error ?? t("reader.unableToOpen"));
    return (
      <div className="reader-loading">
        <p className="reader-error">{message}</p>
        <button type="button" className="back-button" onClick={() => navigate("/")}>
          {t("reader.backToLibrary")}
        </button>
      </div>
    );
  }

  return (
    <Suspense
      fallback={
        <div className="reader-loading">
          <div className="spinner" />
        </div>
      }
    >
      <div className="reader-container" data-theme={settings.theme}>
        <ReaderToolbar
          bookTitle={book.title}
          chapterTitle={chapterTitle || t("reader.reading")}
          progress={progressForToolbar}
          onBack={() => navigate("/")}
          onToggleToc={() => setTocOpen((v) => !v)}
          onToggleSettings={() => setSettingsOpen((v) => !v)}
          onToggleMarkers={() => setMarkersOpen((v) => !v)}
        />

        <PdfLimitationsNotice bookId={bookId} />

        <TableOfContents
          items={tocItems}
          isOpen={tocOpen}
          onClose={() => setTocOpen(false)}
          onNavigate={handleTocNavigate}
        />

        <BookMarkersPanel
          ebookId={bookId}
          isOpen={markersOpen}
          onClose={() => setMarkersOpen(false)}
          onGoToPassage={handleGoToMarker}
        />

        <ReadingSettingsPanel
          format="pdf"
          settings={settings}
          pdfScale={scale}
          onPdfScaleChange={setScale}
          isOpen={settingsOpen}
          onClose={() => setSettingsOpen(false)}
          onUpdate={updateSettings}
          onFlush={flushSettings}
        />

        {pendingSelection && (
          <SelectionPopover
            ebookId={bookId}
            selection={pendingSelection}
            onClose={clearSelection}
            onSaved={clearSelection}
          />
        )}

        <main className="reader-pdf-container">
          <div className="reader-pdf-scroll">
            <PdfViewer
              document={pdfDocument}
              pageNumber={currentPage}
              scale={scale}
              highlights={pdfHighlights}
              pageWrapRef={pageWrapRef}
            />
          </div>
          <BookmarkReaderRail
            items={railItems}
            onGoToBookmark={beginBookmarkPeek}
          />
          <button
            type="button"
            className="reader-page-nav reader-page-nav--prev"
            onClick={goToPrevPage}
            disabled={currentPage <= 1}
            aria-label={t("reader.prevPage")}
          >
            ‹
          </button>
          <ResumeReadingButton
            visible={isBookmarkPeekActive && readingAnchor != null}
            onResume={resumeReadingAnchor}
          />
          <button
            type="button"
            className="reader-page-nav reader-page-nav--next"
            onClick={goToNextPage}
            disabled={currentPage >= pageCount}
            aria-label={t("reader.nextPage")}
          >
            ›
          </button>
        </main>
      </div>
    </Suspense>
  );
}
