"use client"

import { Badge, Popover, Spin } from "antd"
import classNames from "classnames"
import { customNotiCss } from "./style"
import { PAGINATION, ICON_NOTI } from "@/config/constant"
import { INotiContent } from "@/type/Common"
import Image from "next/image"
import { useEffect, useState } from "react"
import { useTranslations } from "next-intl"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faBell } from "@fortawesome/free-regular-svg-icons"
import { useGetNotifications, useGetNotificationsStatus, useUpdateNotifications } from "@/hook/useUsers"
import { useNotificationContext } from "@component/Layout/NotificationContext"
import { css } from "@emotion/css"
import { useRouter } from "@/i18n/routing"
import { useSetRecoilState } from "recoil"
import { modalFeedSelectState, typeMediaState } from "@/recoil"

interface IProps {
  classNameBtn?: string
}

export default function NotiBox(props: IProps) {
  const { notify } = useNotificationContext()

  const trans = useTranslations("general")
  const transMessage = useTranslations("message")
  const router = useRouter()

  const [isOpenNoti, setIsOpenNoti] = useState(false)
  const [page, setPage] = useState(PAGINATION.DEFAULT_CURRENT_PAGE)
  const [totalPage, setTotalPage] = useState(0)
  const [query, setQuery] = useState({ pageNum: page, pageSize: PAGINATION.DEFAULT_PAGE_SIZE })
  const [dataNoti, setDataNoti] = useState<any[]>([])

  const { data: notifications, isLoading } = useGetNotifications(query)
  const { data: notificationStatus } = useGetNotificationsStatus()
  const updateNotification = useUpdateNotifications()
  const setModalFeed = useSetRecoilState(modalFeedSelectState)
  const setTypeMedia = useSetRecoilState(typeMediaState)

  const handleScroll = (e: any) => {
    const { scrollTop, scrollHeight, clientHeight } = e.target
    if (scrollTop + clientHeight >= scrollHeight - 5) {
      if (page < totalPage && !isLoading) {
        setPage(page + 1)
        setQuery({ ...query, pageNum: page + 1 })
      }
    }
  }

  useEffect(() => {
    const mainElement = document.getElementById("content_notification")

    const handleScroll = () => {
      if (mainElement) {
        const { scrollTop, scrollHeight, clientHeight } = mainElement
        if (scrollTop + clientHeight >= scrollHeight - 5) {
          if (page < totalPage && !isLoading) {
            setPage(page + 1)
            setQuery({ ...query, pageNum: page + 1 })
          }
        }
      }
    }

    if (mainElement) {
      mainElement.addEventListener("scroll", handleScroll)
    }

    return () => {
      if (mainElement) {
        mainElement.removeEventListener("scroll", handleScroll)
      }
    }
  }, [])

  useEffect(() => {
    if (notifications?.data) {
      setTotalPage(notifications.data.total_pages || 0)

      const newNotifications =
        notifications.data.notifications?.map((item) => {
          const matchedIcon = ICON_NOTI.find((icon) => icon.label.includes(item.title))
          return {
            ...item,
            icon: matchedIcon ? matchedIcon.icon : "",
            url: matchedIcon ? matchedIcon.url : "",
          }
        }) || []

      setDataNoti((prev) => [...prev, ...newNotifications])
    }
  }, [notifications?.data])

  const handleUpdateNotification = (ids: string, module: string, url: string, module_item_id: string) => {
    handleHideNoti()
    updateNotification
      .mutateAsync(ids)
      .then((res) => {
        if (res?.status === 200) {
          setDataNoti((prevDataNoti) => prevDataNoti?.map((iNoti) => (iNoti?.id === ids ? { ...iNoti, is_read: true } : iNoti)))
        }
      })
      .catch((errors) => {
        notify({
          type: "error",
          message: transMessage("something_wrong"),
          description: errors?.response?.data?.msgs || transMessage("fail"),
        })
      })

    setTimeout(() => {
      if (module && module === "game" && module_item_id) {
        router.push(`/wgn/detail/${module_item_id}`)
      } else if (module && module === "music_album" && module_item_id) {
        router.push(`/music?album=${module_item_id}`)
      } else if (module && module === "photo" && module_item_id) {
        router.push(`/media?album=${module_item_id}`)
      } else if (module && module === "video_album" && module_item_id) {
        setTypeMedia("video")
        router.push(`/media?album=${module_item_id}`)
      } else if (url) {
        router.push(url)
        if (module && (module === "book" || module === "kuisine" || module === "fleamarket")) {
          setModalFeed(module_item_id)
        }
      }
    }, 300)
  }

  const handleHideNoti = () => {
    setIsOpenNoti(false)
  }

  const handleOpenNoti = (newOpen: boolean) => {
    setIsOpenNoti(newOpen)
  }

  const RenderNotiContent = ({ src_icon, alt_icon, title, desc, isRead, ids, module, url, module_item_id, thumbnail_url, module_item_title }: INotiContent) => {
    return (
      <div
        className="flex p-4 items-start border-b border-[var(--secondary-20)] cursor-pointer"
        onClick={() => {
          handleUpdateNotification(ids, module, url, module_item_id)
        }}>
        <Image
          src={thumbnail_url ? thumbnail_url : src_icon || "/img/default_image.jpg"}
          alt={alt_icon || "no-image"}
          width={128}
          height={96}
          className={`h-24 w-32 object-cover shrink-0 ${(isRead && "opacity-40") || ""}`}
          onError={(e) => (e.currentTarget.src = "/img/default_image.jpg")}
        />
        <div className="pl-2 xl:pl-3 grow">
          <p className={`text-base leading-[22px] font-semibold text-[var(--secondary-100)] line-clamp-1 mb-0.5 relative -top-1 ${(isRead && "opacity-40") || ""}`}>
            {title}
          </p>
          <p className={`text-sm leading-[20px] font-normal text-[var(--secondary-70)] line-clamp-2 ${(isRead && "opacity-40") || ""}`}>{desc}</p>
          <p className={`text-base font-semibold line-clamp-2 text-primary-70 ${(isRead && "opacity-40") || ""}`}>{module_item_title}</p>
        </div>
      </div>
    )
  }

  const renderTitleNoti = () => (
    <div className="flex justify-between items-center p-4 border-b-[1px] border-solid border-[var(--secondary-20)]">
      <p className="text-base leading-[22px] font-semibold text-[var(--secondary-100)]">{trans("notification")}</p>
      <button onClick={handleHideNoti}>
        <Image
          src={"/img/icon/close_x.svg"}
          alt={"close_x"}
          width={40}
          height={40}
        />
      </button>
    </div>
  )

  const customCss = css`
    .ant-badge-multiple-words {
      padding: 0 4px;
    }
  `

  return (
    <Popover
      className={classNames("w-14 h-14")}
      content={
        <div
          id="content_notification"
          onScroll={handleScroll}
          className="max-h-[80vh] overflow-y-auto">
          {dataNoti.map((noti, index) => (
            <RenderNotiContent
              title={noti?.title}
              desc={noti?.message}
              src_icon={noti?.icon}
              alt_icon={noti?.title}
              isRead={noti?.is_read}
              key={noti?.id}
              ids={`${noti?.id}`}
              module={noti?.module}
              url={noti?.url}
              module_item_id={noti?.module_item_id}
              thumbnail_url={noti?.thumbnail_url}
              module_item_title={noti?.module_item_title || ""}
            />
          ))}
          {isLoading ? (
            <div className="w-full h-9 my-2 flex justify-center">
              <Spin />{" "}
            </div>
          ) : null}
        </div>
      }
      overlayClassName={classNames(customNotiCss)}
      title={renderTitleNoti()}
      trigger="click"
      placement={"left"}
      open={isOpenNoti}
      onOpenChange={handleOpenNoti}>
      <button
        type="button"
        className={classNames(
          "border border-[var(--secondary-20)] rounded-lg hover:text-[var(--primary--70)] hover:border-[var(--primary--70)]",
          props?.classNameBtn || "",
          customCss,
        )}>
        <Badge
          count={notificationStatus?.data?.unread || 0}
          size="small"
          overflowCount={9}
          offset={[-3, 3]}>
          <FontAwesomeIcon
            icon={faBell}
            className="text-2xl"
          />
        </Badge>
      </button>
    </Popover>
  )
}
