import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination";
import { useDateContext } from "@/context/DateContext";
import { useEffect, useMemo, useState } from "react";

import {
  autoPlaceArticles,
  createArticlesFromFilenames,
  isSameDay,
} from "../../utils/helpers";
import { usePageContext } from "@/context/PageContext";

// Type Definitions
interface ArticleImage {
  page: number;
  date: string;
  articles: string[];
}

interface Origin {
  x: number;
  y: number;
}

const NewspaperViewer = () => {
  const { currentPage, setCurrentPage } = usePageContext();
  const [selectedArticle, setSelectedArticle] = useState<string | null>(null);
  const [images, setImages] = useState<ArticleImage[]>([]);
  const [colCount, setColCount] = useState(8);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const { date } = useDateContext();
  const [origin, setOrigin] = useState<Origin>({ x: 0, y: 0 });

  // Update column count based on page
  useEffect(() => {
    setColCount(currentPage === 1 ? 6 : 8);
  }, [currentPage]);

  // Simulated async fetch (replace with actual fetch if needed)
  useEffect(() => {
    const fetchImages = async () => {
      try {
        setIsLoading(true);
        setError(null);

        // Simulate delay
        await new Promise((res) => setTimeout(res, 500));

        setImages([
          {
            page: 1,
            date: "Mon May 13 2025 22:00:46 GMT+0600 (Bangladesh Standard Time)",
            articles: [
              "1_r2_c6.jpg",
              "1_r3_c3.jpg",
              "1_r3_c1.jpg",
              "1_r3_c2.jpg",
              "1_r4_c2.jpg",
              "(1_r4_c1).jpg",
              "(1_r4_c2).jpg",
              "1_r2_c1.jpg",
              "1_r2_c1_g6.jpg",
            ],
          },
          {
            page: 2,
            date: "Mon May 13 2025 22:00:00 GMT+0600 (Bangladesh Standard Time)",
            articles: [
              "2_r1_c8.jpg",
              "2_r2_c2_g1).jpg",
              "2_r1_c2_g3.jpg",
              "2_r1_c4_g5.jpg",
              "(2_r1_c4_g5.jpg",
              "2_r1_c1_g8).jpg",
              "2_r1_c1_g8.jpg",
              "2_r1_c2_g3).jpg",
              "2_r2_c2_g3.jpg",
              "2_r2_c3_g5.jpg",
              "2_r3_c3_g3.jpg",
              "(2_r3_c3)_g5.jpg",
              "(2_r1_c2)_g1.jpg",
              "((2_r1_c2)_g1.jpg",
              "2_r2_c2_g1.jpg",
            ],
          },
        ]);
      } catch (err) {
        setError("Failed to load newspaper data.");
      } finally {
        setIsLoading(false);
      }
    };

    fetchImages();
  }, []);

  const zoomIn = (articleUrl: string, e: React.MouseEvent) => {
    const { clientX, clientY } = e;
    setOrigin({ x: clientX, y: clientY });
    setSelectedArticle(articleUrl);
  };

  const zoomOut = () => {
    setSelectedArticle(null);
  };

  const dateFilteredContent = useMemo(
    () => images.filter((item) => isSameDay(item.date, date)),
    [images, date]
  );

  const hasContentForDate = dateFilteredContent.length > 0;

  const dateArticles = useMemo(
    () =>
      hasContentForDate
        ? dateFilteredContent.flatMap((pageGroup) =>
            createArticlesFromFilenames(pageGroup.articles, pageGroup.page)
          )
        : [],
    [dateFilteredContent, hasContentForDate]
  );

  const currentPageArticles = dateArticles.filter(
    (a) => a.page === currentPage
  );
  const placedArticles = useMemo(
    () => autoPlaceArticles(currentPageArticles, colCount),
    [currentPageArticles, colCount]
  );

  const totalPages = hasContentForDate
    ? Math.max(...dateFilteredContent.map((item) => item.page))
    : 0;

  return (
    <div className="w-3/4 mx-auto">
      {isLoading ? (
        <div className="flex justify-center items-center h-64">Loading...</div>
      ) : error ? (
        <div className="text-red-600 text-center h-64 flex items-center justify-center">
          {error}
        </div>
      ) : hasContentForDate ? (
        <>
          {/* Pagination */}
          <section className="my-4">
            <Pagination>
              <PaginationContent>
                <PaginationItem>
                  <PaginationPrevious
                    href="#"
                    onClick={(e) => {
                      e.preventDefault();
                      setCurrentPage((prev: number) => Math.max(1, prev - 1));
                    }}
                  />
                </PaginationItem>

                {Array.from({ length: totalPages }, (_, i) => i + 1).map(
                  (n) => (
                    <PaginationItem key={n}>
                      <PaginationLink
                        href="#"
                        isActive={n === currentPage}
                        onClick={(e) => {
                          e.preventDefault();
                          setCurrentPage(n);
                        }}
                      >
                        {n}
                      </PaginationLink>
                    </PaginationItem>
                  )
                )}

                <PaginationItem>
                  <PaginationNext
                    href="#"
                    onClick={(e) => {
                      e.preventDefault();
                      setCurrentPage((prev) => Math.min(totalPages, prev + 1));
                    }}
                  />
                </PaginationItem>
              </PaginationContent>
            </Pagination>
          </section>

          {/* Articles */}
          <section
            className="gap-1"
            style={{
              display: "grid",
              gridTemplateColumns: `repeat(${colCount}, 1fr)`,
            }}
          >
            {placedArticles.map((article) => (
              <div
                key={article.id}
                style={{
                  gridColumn: `${article.gridColumnStart} / span ${article.colSpan}`,
                  gridRow: `${article.gridRowStart} / span ${article.rowSpan}`,
                  overflow: "hidden",
                }}
                className="hover:opacity-60 hover:cursor-pointer transition-opacity"
              >
                <img
                  onClick={(e) => zoomIn(`/${article.image}`, e)}
                  src={`/${article.image}`}
                  alt={`Article ${article.id}`}
                  style={{
                    width: "100%",
                    height: "100%",
                    objectFit: "cover",
                    display: "block",
                  }}
                />
              </div>
            ))}
          </section>
        </>
      ) : (
        <div className="flex flex-col items-center justify-center h-64 text-center">
          <h2 className="text-2xl font-semibold mb-2">
            No newspaper available
          </h2>
          <p className="text-gray-600">
            There is no newspaper edition for{" "}
            {date?.toLocaleDateString("en-US", {
              weekday: "long",
              year: "numeric",
              month: "long",
              day: "numeric",
            })}
          </p>
        </div>
      )}

      {/* Zoomed View */}
      {selectedArticle && (
        <div
          className="fixed inset-0 bg-black/70 flex justify-center items-center z-50"
          onClick={zoomOut}
        >
          <div
            className="relative bg-white rounded-lg overflow-hidden shadow-lg"
            style={{
              animation: "zoomIn 0.3s ease-out",
              transformOrigin: `${origin.x}px ${origin.y}px`,
            }}
            onClick={(e) => e.stopPropagation()}
          >
            <img
              src={selectedArticle}
              alt="Zoomed Article"
              className="rounded max-h-[90vh] max-w-[90vw]"
            />
            <button
              onClick={zoomOut}
              className="absolute top-2 right-2 text-black text-2xl"
              aria-label="Close"
            >
              &times;
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

export default NewspaperViewer;
