"use client";

import {
  Card,
  CardBody,
  CardHeader,
  Checkbox,
  CheckboxGroup,
  Chip,
  Image,
  Modal,
  ModalBody,
  ModalContent,
  ModalFooter,
  ModalHeader,
  useDisclosure,
} from "@nextui-org/react";
import { useRouter } from "next/navigation";
import LoadingBar from "react-top-loading-bar";
import { useEffect, useMemo, useState } from "react";
import { FaChevronDown, FaChevronRight, FaFilter } from "react-icons/fa";
import { IoIosCloseCircle } from "react-icons/io";

import { Post } from "@/types/blog/blogTypes";
import { INTERNAL_PAGES } from "@/constants/pages-mapping/internal-pages-mapping";
import { fetchPostsByTag } from "@/services/blogActions";
import NoResults from "@/components/pages/participant/opportunities/partials/no-results";
import Button from "@/components/common/button";
import { truncateText } from "@/utils/text-utils";

type InsightsHomeProps = {
  posts: Post[];
};

type FirstPost = {
  firstPost: Post;
  translatedTag: string;
  onClickPost: () => void;
};

function FirstPostCard({ firstPost, translatedTag, onClickPost }: FirstPost) {
  return (
    <div className="w-full relative">
      <Image
        alt={firstPost?.feature_image_alt || ""}
        className="object-cover rounded-none h-96 lg:h-[500px] w-screen"
        loading="eager"
        src={firstPost?.feature_image || ""}
      />
      <div className="absolute inset-0 bg-gradient-to-b from-transparent to-black opacity-50 z-10"></div>
      <div className="absolute bottom-0 p-4 z-10 max-w-xl flex flex-col space-y-4">
        <Chip
          classNames={{
            content: "font-bold",
            base: "bg-midnightBlue text-white font-inter text-xs mt-1.5",
          }}
          size="sm"
        >
          {translatedTag}
        </Chip>
        <p className="text-3xl font-noto font-bold text-white">
          {firstPost?.title || ""}
        </p>
        <Button
          btnLabel="Read article"
          className="mt-6 w-72"
          customVariant="client"
          endContent={<FaChevronRight />}
          onClick={onClickPost}
        />
      </div>
    </div>
  );
}

function InsightsHome({ posts: initialPosts }: InsightsHomeProps) {
  const { isOpen, onOpen, onClose } = useDisclosure();
  const router = useRouter();
  const [progress, setProgress] = useState(0);
  const [itemsPerPage, setItemsPerPage] = useState(6);
  const [selectedTags, setSelectedTags] = useState<string[]>([]);
  const [filteredPosts, setFilteredPosts] = useState<Post[]>(initialPosts);
  const [initialHeroPost, setInitialHeroPost] = useState<Post | null>(null);
  const [showChevron, setShowChevron] = useState(true);

  const tagDisplayNames: { [key: string]: string } = {
    "#client-news": "News",
    "#client-case-studies": "Case studies",
    "#client-how-to": "How to",
    "#client-industry-stories": "Industry stories",
    "#client-community-tips": "Community tips",
  };

  const typesOfInsights = [
    { id: "#client-news", title: "News" },
    { id: "#client-case-studies", title: "Case studies" },
    { id: "#client-how-to", title: "How to" },
    { id: "#client-industry-stories", title: "Industry stories" },
    { id: "#client-community-tips", title: "Community tips" },
  ];

  const hasPosts = filteredPosts.length > 0;

  useEffect(() => {
    if (!initialHeroPost) {
      const sortedInitialPosts = initialPosts.sort((a, b) => {
        const publishDateA = new Date(a.published_at);
        const publishDateB = new Date(b.published_at);
        return publishDateB.getTime() - publishDateA.getTime();
      });
      setInitialHeroPost(sortedInitialPosts[0]);
    }
  }, [initialHeroPost, initialPosts]);

  useEffect(() => {
    const getFilteredPosts = async () => {
      setProgress(50);
      const fetchedPosts = await fetchPostsByTag(selectedTags);
      setFilteredPosts(fetchedPosts.posts);
      setProgress(100);
    };

    if (selectedTags.length > 0) {
      getFilteredPosts();
    } else {
      setFilteredPosts(initialPosts);
    }
  }, [initialPosts, selectedTags]);

  useEffect(() => {
    const handleScroll = () => {
      if (window.scrollY > 0) {
        setShowChevron(false);
      }
    };

    window.addEventListener("scroll", handleScroll);

    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  const sortedPosts = useMemo(() => {
    if (!filteredPosts) {
      return [];
    }

    return [...filteredPosts].sort((a, b) => {
      const publishDateA = new Date(a.published_at);
      const publishDateB = new Date(b.published_at);

      return publishDateB.getTime() - publishDateA.getTime();
    });
  }, [filteredPosts]);

  const handleTagRemove = (tag: string) => {
    setSelectedTags(selectedTags.filter((t) => t !== tag));
  };

  const handleFilterChange = (newValues: string[]) => {
    setSelectedTags(newValues);
    // removed by request of the team on functional testing.
    // window.scrollTo({ top: 0, behavior: "smooth" });
  };

  const handleOnPress = (slug: string) => {
    router.push(`${INTERNAL_PAGES.client.insights}/${slug}`);
  };

  const increaseItems = () => {
    setItemsPerPage(
      (prevItemsToShow) =>
        prevItemsToShow + (window.innerWidth <= 1024 ? 9 : 18)
    );
  };

  const handleClearFilters = () => {
    setSelectedTags([]);
  };

  useEffect(() => {
    const handleScroll = () => {
      const scrollPosition =
        window.scrollY || document.documentElement.scrollTop;
      const windowHeight = window.innerHeight;
      const documentHeight = document.documentElement.offsetHeight;

      // This threshold value is required for mobile and tablets, otherwise the user will have to scroll until the bottom of the page, past footer.
      const threshold = window.innerWidth <= 1024 ? 500 : 1000;

      if (window.innerWidth <= 1024) {
        if (windowHeight + scrollPosition >= documentHeight - threshold) {
          setProgress(50);
          increaseItems();
          setProgress(100);
        }
      } else {
        if (windowHeight + scrollPosition >= documentHeight) {
          setProgress(50);
          increaseItems();
          setProgress(100);
        }
      }
    };

    window.addEventListener("scroll", handleScroll);
    window.addEventListener("touchmove", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll);
      window.removeEventListener("touchmove", handleScroll);
    };
  }, []);

  const showClearAllBtn = selectedTags.length > 0;

  return (
    <div className="min-h-screen pb-24">
      {initialHeroPost && (
        <FirstPostCard
          firstPost={initialHeroPost}
          translatedTag={tagDisplayNames[initialHeroPost.tags[0]?.name]}
          onClickPost={() => handleOnPress(initialHeroPost.slug)}
        />
      )}
      {showChevron && (
        <div className="fixed inset-x-0 bottom-0 flex justify-center z-50">
          <FaChevronDown className="text-4xl text-pfrBasicBlue animate-bounce" />
        </div>
      )}
      <div className="lg:ps-8 pt-20 max-w-5xl">
        <h1 className="text-5xl font-black font-inter relative text-center lg:text-start px-4 lg:px-0">
          Voices in research
        </h1>
        <h2 className="font-noto text-base lg:text-xl mt-4 text-black dark:text-white text-center lg:text-start mx-8 lg:mx-0">
          The latest case studies, industry insights, company news and more from
          People for Research. Dive into our expertise in participant
          recruitment and user research operations, and learn how we collaborate
          with our clients to drive impactful research across a variety of
          sectors.
        </h2>
      </div>
      <div className="flex flex-col lg:flex-row lg:space-x-4">
        {/* Desktop filters */}
        <div className="hidden lg:flex lg:flex-col mt-12 py-12 ps-8 space-y-6 w-[500px]">
          <div className="flex justify-between space-x-4">
            <h4 className="inline-flex font-inter items-center font-black text-2xl text-black dark:text-white tracking-tight">
              <FaFilter className="size-4 me-2" />
              Filters
            </h4>
            {showClearAllBtn && (
              <Button
                btnLabel="Clear"
                customVariant="transparent"
                endContent={<IoIosCloseCircle className="size-4" />}
                size="sm"
                onClick={handleClearFilters}
              />
            )}
          </div>
          <CheckboxGroup value={selectedTags} onChange={handleFilterChange}>
            {typesOfInsights.map((tag) => (
              <Checkbox key={tag.id} color="default" value={tag.id}>
                {tag.title}
              </Checkbox>
            ))}
          </CheckboxGroup>
        </div>
        {/* Mobile filters */}
        <div className="flex m-auto p-4 xl:hidden">
          <Button
            btnLabel="Filters"
            className="text-black dark:text-white font-inter font-bold"
            endContent={<FaFilter className="size-3" />}
            size="sm"
            variant="ghost"
            onClick={onOpen}
          />
        </div>
        {!hasPosts && (
          <div className="w-full mt-20 px-8 lg:px-0">
            <NoResults isClient />
          </div>
        )}
        {hasPosts && (
          <div className="flex flex-col">
            <div className="flex flex-col mt-4 lg:mt-20">
              <div className="flex mt-4 flex-wrap gap-2 items-center justify-center lg:items-start lg:justify-start">
                {selectedTags.map((tag) => (
                  <Chip
                    key={tag}
                    isCloseable
                    classNames={{
                      content: "font-semibold font-bold",
                      base: "bg-midnightBlue p-0 text-start text-white font-inter text-xs px-2",
                    }}
                    onClose={() => handleTagRemove(tag)}
                  >
                    {tagDisplayNames[tag] || tag}
                  </Chip>
                ))}
              </div>
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xxl:grid-cols-4 xxxl:grid-cols-5 gap-8 mt-8 mx-12 lg:mx-0 lg:pe-12">
                {sortedPosts.slice(0, itemsPerPage).map((post) => (
                  <Card
                    key={post.id}
                    disableAnimation
                    isHoverable
                    isPressable
                    className="light shadow-none relative flex w-full text-left bg-center bg-cover cursor-pointer group rounded-lg hover:cursor-pointer hover:outline-offset-1 hover:outline-2 hover:outline-pfrBasicBlue/50 hover:dark:outline-pfrBasicBlue"
                    onPress={() => handleOnPress(post.slug)}
                  >
                    {post.feature_image && (
                      <CardHeader className="p-0 w-full">
                        <Image
                          alt={post.feature_image_alt || post.title}
                          className="object-cover w-[500px] rounded-none"
                          height={200}
                          loading="eager"
                          src={post.feature_image}
                        />
                      </CardHeader>
                    )}
                    <CardBody className="p-6">
                      <div className="font-noto text-xs text-gray-500 flex flex-row justify-between">
                        <span className="hidden lg:block">
                          {post.reading_time} min read
                        </span>
                      </div>
                      <span className="font-inter font-bold text-black py-2 leading-6">
                        {post.title.length > 75
                          ? truncateText(post.title, 75)
                          : post.title}
                      </span>
                      <span className="block lg:hidden font-noto text-xs text-gray-500 mb-4">
                        {post.reading_time} min read
                      </span>
                      <Chip
                        classNames={{
                          content: "font-semibold font-bold",
                          base: "bg-midnightBlue p-0 text-white font-inter text-xs",
                        }}
                      >
                        {tagDisplayNames[post.tags[0].name]}
                      </Chip>
                    </CardBody>
                  </Card>
                ))}
              </div>
            </div>
            {itemsPerPage >= sortedPosts.length && (
              <div className="flex justify-center items-center mt-6 text-center mx-8 lg:mx-0">
                <p className="font-medium text-xs text-black/50 dark:text-white">
                  You&apos;ve reached the end of the current listings. Please
                  check back soon for new insights written by our team.
                </p>
              </div>
            )}
          </div>
        )}
      </div>
      {/* Loading bar */}
      <LoadingBar
        className="bg-pfrBasicBlue"
        height={4}
        progress={progress}
        onLoaderFinished={() => setProgress(0)}
      />
      {/* Filters modal (mobile only) */}
      <Modal
        backdrop="blur"
        isOpen={isOpen}
        scrollBehavior="inside"
        size="full"
        onClose={onClose}
      >
        <ModalContent>
          <ModalHeader className="flex flex-col gap-1">
            <h4 className="inline-flex font-inter items-center font-black text-2xl text-black dark:text-white tracking-tight">
              <FaFilter className="size-4 me-2" />
              Filters
            </h4>
          </ModalHeader>
          <ModalBody>
            <CheckboxGroup value={selectedTags} onChange={handleFilterChange}>
              {typesOfInsights.map((tag) => (
                <Checkbox key={tag.id} color="default" value={tag.id}>
                  {tag.title}
                </Checkbox>
              ))}
            </CheckboxGroup>
          </ModalBody>
          <ModalFooter>
            {showClearAllBtn && (
              <Button
                fullWidth
                btnLabel="Clear all filters"
                customVariant="transparent"
                size="sm"
                onClick={handleClearFilters}
              />
            )}
          </ModalFooter>
        </ModalContent>
      </Modal>
    </div>
  );
}

export default InsightsHome;
