import * as React from "react";
import { memo, useContext, useEffect, useState } from "react";
import { inputProps } from "../../interface/inputfieldProps";
import { withJsonFormsControlProps } from "@jsonforms/react";
import { DataContext } from "../../context/Context";
import { Box } from "@mui/system";
import { CircularProgress, IconButton, Typography, useMediaQuery, useTheme } from "@mui/material";
import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos";
import * as pdfjsLib from "pdfjs-dist";
import type { PDFDocumentProxy } from "pdfjs-dist";
import PdfPageRenderer from "./PdfPageRenderer";
import workerSrc from "pdfjs-dist/build/pdf.worker.mjs?url";

pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;

const PdfViewer = memo(function (props: inputProps) {
  const { uischema, data } = props;
  const { theme } = useContext(DataContext);
  const uischemaData = uischema?.config?.main;
  const styleConfig = uischema?.config?.style;
  const muiTheme = useTheme();
  const isSmallScreen = useMediaQuery(muiTheme.breakpoints.down("sm"));

  const [pdf, setPdf] = useState<PDFDocumentProxy | null>(null);
  const [pdfError, setPdfError] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(1);
  const [isLoading, setIsLoading] = useState(false);

  const pdfRef = React.useRef<PDFDocumentProxy | null>(null);
  useEffect(() => {
    let cancelled = false;
    let loadingTask: pdfjsLib.PDFDocumentLoadingTask | null = null;

    const loadPdf = async () => {
      if (!data) return;
      setIsLoading(true);
      setPdfError(null);
      try {
        const bytes = Uint8Array.from(window.atob(data), (char) => char.charCodeAt(0));
        loadingTask = pdfjsLib.getDocument({ data: bytes });
        const pdfDocument = await loadingTask.promise;
        if (cancelled) {
          pdfDocument.destroy();
          return;
        }
        pdfRef.current?.destroy();
        pdfRef.current = pdfDocument;
        setPdf(pdfDocument);
        setCurrentPage(1);
      } catch (e: unknown) {
        if (!cancelled) {
          setPdfError(e instanceof Error ? e?.message : "Failed to load PDF.");
        }
      } finally {
        if (!cancelled) setIsLoading(false);
      }
    };

    loadPdf();
    return () => {
      cancelled = true;
      loadingTask?.destroy();
      pdfRef.current?.destroy();      
      pdfRef.current = null;
      setPdf(null);
    };
  }, [data]);

  const totalPages = pdf?.numPages ?? 0;
  return (
    <React.Fragment>
      {isLoading ? (
        <Box sx={{ display: "flex", justifyContent: "center", p: 4 }}>
          <CircularProgress size={36} />
        </Box>
        ) : pdf ? (
          <Box sx={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "16px", width: "100%" }}>
            <Box sx={{ borderRadius: "8px", overflow: "hidden", boxShadow: "0 4px 20px rgba(0,0,0,0.12)", lineHeight: 0 }}>
              <PdfPageRenderer
                currentPage={currentPage}
                pdf={pdf}
                scale={!isSmallScreen ? uischemaData?.scale || 1 : 0.5}
                theme={theme}
                styleConfig={styleConfig}
              />
            </Box>

            {totalPages > 1 && (
              <Box
                sx={{
                  display: "flex",
                  alignItems: "center",
                  gap: 1,
                  px: 2,
                  py: 0.75,
                  borderRadius: "999px",
                  backgroundColor: theme?.myTheme?.palette?.secondary?.main ?? "#F0F3F6",
                  border: `1px solid ${theme?.myTheme?.palette?.secondary?.light ?? "#D1D3D4"}`,
                  boxShadow: "0 1px 4px rgba(0,0,0,0.06)",
                }}
                role="navigation"
                aria-label="PDF page navigation"
              >
                <IconButton
                  onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
                  disabled={currentPage === 1}
                  size="small"
                  aria-label="Previous page"
                  aria-disabled={currentPage === 1}
                  sx={{
                    color: currentPage === 1 ? "text.disabled" : theme?.myTheme?.palette?.primary?.main,
                    "&:hover": { backgroundColor: `${theme?.myTheme?.palette?.primary?.light}22` },
                    transition: "color 0.2s",
                  }}
                >
                  <ArrowBackIosNewIcon sx={{ fontSize: 14 }} />
                </IconButton>

                <Typography
                  variant="body2"
                  sx={{ minWidth: 72, textAlign: "center", fontWeight: 500, fontSize: "0.8rem", color: "text.secondary", userSelect: "none" }}
                >
                  {currentPage} <span style={{ opacity: 0.45 }}>/</span> {totalPages}
                </Typography>

                <IconButton
                  onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
                  disabled={currentPage === totalPages}
                  size="small"
                  aria-label="Next page"
                  aria-disabled={currentPage === totalPages}
                  sx={{
                    color: currentPage === totalPages ? "text.disabled" : theme?.myTheme?.palette?.primary?.main,
                    "&:hover": { backgroundColor: `${theme?.myTheme?.palette?.primary?.light}22` },
                    transition: "color 0.2s",
                  }}
                >
                  <ArrowForwardIosIcon sx={{ fontSize: 14 }} />
                </IconButton>
              </Box>
            )}
          </Box>
        ) : pdfError ? (
          <Box
            sx={{
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              p: 3,
              borderRadius: "8px",
              backgroundColor: "#fff5f5",
              border: "1px solid #ffcccc",
              color: "error.main",
              fontSize: "0.875rem",
            }}
          >
            {pdfError}
          </Box>
        ) : null}
    </React.Fragment>
  );
});

export default withJsonFormsControlProps(PdfViewer);