"use client"

import { List } from "antd"
import { find, flattenDeep, isEmpty, omit, omitBy } from "lodash"
import { useCallback, useEffect, useMemo, useState } from "react"
import classNames from "classnames"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faAngleRight } from "@fortawesome/free-solid-svg-icons"
import { useTranslations } from "next-intl"
import { useRecoilState, useRecoilValue } from "recoil"
import Image from "next/image"
import type { MenuProps } from "antd"
import { useSearchParams } from "next/navigation"

import { usePathname, useRouter } from "@/i18n/routing"
import SearchBoxCategory from "./SearchBoxCategory"
import NotFoundBox from "@/component/Notfound"
import { useAddMarketFavourite, useGetMarketCategories, useGetMarketList, useRemoveMarketFavourite } from "@/hook/useMarket"
import { IMarketCategoryQuery, IMarketItems, IOnMarketQuery } from "@/type/Market"
import { marketOptions } from "@/config/constant"
import HeaderBreadcrumb from "@/component/Layout/HeaderBreadcrumb"
import SearchBox from "@/component/Layout/SearchBox"
import { CustomDropDownMenuCss, DropDownMenu } from "@/component/Common/DropDownMenu"
import { categoryBookState, typeMarketState } from "@/recoil"
import { OnMarketCss } from "./style"
import { CardItemMarket, arrIconCategories, renderTags } from "../common"
import { LoadingResult } from "@/component/Common/LoadingResult/LoadingResult"
import { LoadMoreInfinite } from "@/component/Common/LoadMoreInfinite"
import { useNotificationContext } from "@/component/Layout/NotificationContext"
import { useQueryClient } from "@tanstack/react-query"
import { renderLabelItem } from "@/component/Common/LabelItem"

export default function OnMarket() {
  const router = useRouter()
  const pathname = usePathname()
  const options = marketOptions()
  const searchParams = useSearchParams()
  const queryClient = useQueryClient()
  const typeMarket = useRecoilValue(typeMarketState)
  const oldSearch = Object.fromEntries(searchParams.entries())
  const { renderLabelBottom } = renderTags()
  const { notify } = useNotificationContext()

  const trans = useTranslations("market")
  const transBook = useTranslations("book")
  const transButton = useTranslations("button")
  const transMusic = useTranslations("music")
  const transMessage = useTranslations("message")
  const transContact = useTranslations("contact")

  const [queryCategory, setQueryCategory] = useState<IMarketCategoryQuery | any>({})
  const [isNextPage, setIsNextPage] = useState(true)
  const [queryMarket, setQueryMarket] = useState<IOnMarketQuery>({})
  const [selectedKey, setSelectedKey] = useRecoilState(categoryBookState)
  const [activeButtons, setActiveButtons] = useState<any>("")
  const [searchCate, setSearchCate] = useState("")
  const [searchValue, setSearchValue] = useState("")

  const { data: marketCategories, isLoading: loadingCate } = useGetMarketCategories(queryCategory)
  const { data: marketListByCateID, isLoading, fetchNextPage, hasNextPage } = useGetMarketList(queryMarket)
  const addFavourite = useAddMarketFavourite()
  const removeFavourite = useRemoveMarketFavourite()

  const dataMarkets = useMemo(
    () =>
      flattenDeep(marketListByCateID?.pages.map((e: any) => e.marketListByCateID!)).length > 0
        ? flattenDeep(marketListByCateID?.pages.map((e: any) => e?.data?.data?.items))
        : [],
    [marketListByCateID?.pages],
  )

  useEffect(() => {
    if (Number(marketListByCateID?.pageParams?.at(-1)) >= Number(marketListByCateID?.pages?.at(-1)?.data?.data?.total_pages)) {
      setIsNextPage(false)
    }
    if (!isNextPage && Number(marketListByCateID?.pageParams?.at(-1)) < Number(marketListByCateID?.pages?.at(-1)?.data?.data?.total_pages)) {
      setIsNextPage(true)
    }
  }, [isNextPage, marketListByCateID?.pages, marketListByCateID?.pageParams])

  const dataCategories = useMemo(() => {
    const arrCategories = new Map(arrIconCategories?.map((item: any) => [item.name, item]))

    const mergedArrayForum = !isEmpty(arrCategories)
      ? marketCategories?.data?.data?.categories?.map((item) => ({
          ...item,
          ...arrCategories.get(item.name),
        })) || []
      : []

    const newArrCate = [{ name: "All", id: "all", iconWhite: "All_W.svg", iconBlack: "All_B.svg" }, ...mergedArrayForum]

    return newArrCate
  }, [marketCategories?.data?.data?.categories])

  const handleOpenChange = (open: boolean, item: IMarketItems) => {
    setActiveButtons((prevId: any) => (prevId === item?.id || !open ? null : item?.id))
  }

  const buttonTopRight = (item: IMarketItems, className?: string) => {
    const items: MenuProps["items"] = [
      {
        label: renderLabelItem(transBook("go_detail"), "/img/icon/information_circle_outline.svg", "information_circle_outline"),
        key: "0",
        onClick: () => {
          router.push(`/market/${activeButtons}`)
        },
      },
      item?.is_favourite
        ? {
            label: renderLabelItem(transContact("remove_favorite"), "/img/icon/broken_heart.svg", transContact("remove_favorite")),
            key: "1",
            onClick: () => handleRemoveFavorite(item.id),
          }
        : {
            label: renderLabelItem(transBook("add_to_favorite"), "/img/icon/heart_outline.svg", transBook("add_to_favorite")),
            key: "2",
            onClick: () => handleAddFavorite(item.id),
          },
    ]

    return (
      <DropDownMenu
        className={`${className || ""}`}
        menu={{ items, className: classNames(CustomDropDownMenuCss) }}
        onOpenChange={(open) => {
          handleOpenChange(open, item)
        }}
      />
    )
  }

  const renderLabelTab = (title: string, src_icon: string, clicked: boolean) => {
    return (
      <div
        className={`max-h-[66px] h-[66px] text-sm flex md:py-2 lg:py-4 justify-between items-center w-[15rem] lg:w-full rounded-lg border border-solid border-[var(--secondary-20)] ${
          clicked ? "text-white bg-[var(--secondary-100)]" : "text-[var(--secondary-100)] bg-[var(--secondary-10)]"
        }`}>
        <div className="text-sm flex items-center ml-3">
          <Image
            src={src_icon}
            alt={title}
            width={32}
            height={32}
            onError={(e) => (e.currentTarget.src = "/img/default_image.jpg")}
          />
          <p className="pl-2 xl:pl-4 font-weight line-clamp-1">{title}</p>
        </div>
        <div className="mr-3 ml-1">
          <FontAwesomeIcon icon={faAngleRight} />
        </div>
      </div>
    )
  }

  const RenderSearch = () => (
    <div>
      <SearchBoxCategory
        header={trans("categories")}
        value={searchCate}
        onSearch={handleSearchCategory}
        onChange={setSearchCate}
        placeholder={trans("search_categories")}
        classNameBoxSearch="h-12"
        classInput="!h-12 lg:!w-56 xl:!w-56"
        disabled={loadingCate}
      />
    </div>
  )

  const updateSearchQuery = useCallback(
    (updatedQuery: any) => {
      const params = new URLSearchParams(searchParams)

      if (Object.keys(updatedQuery).length === 0) {
        router.push(pathname, { scroll: false })
      } else {
        Object.entries(updatedQuery).forEach(([key, value]) => {
          value ? params.set(key, String(value)) : params.delete(key)
        })

        Array.from(params.keys()).forEach((key) => {
          if (!(key in updatedQuery)) {
            params.delete(key)
          }
        })
        router.push(`${pathname}?${params.toString()}`, { scroll: false })
      }
    },
    [searchParams, pathname, queryCategory, queryMarket],
  )

  const handleSearchCategory = (keyword: string) => {
    if (keyword && keyword?.length >= 3) {
      const updatedQuery = { ...oldSearch, searchCate: keyword?.trim() }
      const cleanedObj = omitBy(updatedQuery, (value) => value === null || value === undefined || value === "")
      setQueryCategory({ search: updatedQuery?.searchCate })
      updateSearchQuery(cleanedObj)
    }
    if (keyword === "" && oldSearch?.searchCate) {
      const updatedQuery = { ...oldSearch, searchCate: "" }
      const cleanedObj = omitBy(updatedQuery, (value) => value === null || value === undefined || value === "")
      setQueryCategory({})
      updateSearchQuery(cleanedObj)
    }
  }

  const handleSearchKeyword = (keyword: string) => {
    if (keyword && keyword?.length >= 3) {
      const updatedQuery = { ...oldSearch, searchTitle: keyword?.trim() }
      const cleanedObj = omitBy(updatedQuery, (value) => value === null || value === undefined || value === "")

      setSelectedKey("all")
      setQueryMarket((preV) => ({ ...preV, ...cleanedObj }))
      updateSearchQuery(cleanedObj)
    }
    if (keyword === "" && oldSearch?.searchTitle) {
      const updatedQuery = { ...oldSearch, searchTitle: "" }
      const cleanedObj = omitBy(updatedQuery, (value) => value === null || value === undefined || value === "")
      setQueryMarket((preV) => ({ ...omit(preV, ["searchTitle"]) }))
      updateSearchQuery(cleanedObj)
    }
  }

  const handleAddFavorite = (id: string) => {
    addFavourite
      .mutateAsync(id)
      .then(() => {
        notify({
          type: "success",
          message: transMessage("congratulation"),
          description: transMessage("add_favorite_success"),
        })
        queryClient.invalidateQueries({ queryKey: ["market.get_list_by_category_id", queryMarket] })
        queryClient.invalidateQueries({ queryKey: ["market.get_favourite_list"] })
      })
      .catch((error) => {
        notify({
          type: "error",
          message: transMessage("something_wrong"),
          description: error?.response?.data.msgs || transMessage("fail"),
        })
      })
  }

  const handleRemoveFavorite = (id: string) => {
    removeFavourite
      .mutateAsync(id)
      .then(() => {
        notify({
          type: "success",
          message: transMessage("congratulation"),
          description: transMessage("remove_favorite_success"),
        })
        queryClient.invalidateQueries({ queryKey: ["market.get_list_by_category_id", queryMarket] })
        queryClient.invalidateQueries({ queryKey: ["market.get_favourite_list"] })
      })
      .catch((error) => {
        notify({
          type: "error",
          message: transMessage("something_wrong"),
          description: error?.response?.data.msgs || transMessage("fail"),
        })
      })
  }

  return (
    <>
      <HeaderBreadcrumb
        items={[
          {
            aria_label: find(options, { value: typeMarket as string })?.label || "",
            href: "#",
            title: find(options, { value: typeMarket as string })?.label || "",
          },
        ]}
        slot={
          <div>
            <SearchBox
              value={searchValue}
              onSearch={handleSearchKeyword}
              onChange={setSearchValue}
              placeholder={trans("search_items_here")}
              className="h-12"
              classInput="!h-12 lg:!w-56 xl:!w-56"
              classButton="!h-12 md:!pl-2"
            />
          </div>
        }
        showButton={false}
      />

      <div className={classNames("h-full grow overflow-y-auto lg:flex", OnMarketCss)}>
        <List
          loading={loadingCate}
          className={classNames("min-w-[15rem] xl:min-w-[17.5rem] !m-5 lg:!mr-4 overflow-hidden flex flex-col custom_list")}
          header={RenderSearch()}
          bordered
          dataSource={dataCategories}
          renderItem={(item) => (
            <List.Item
              className="py-1 !px-2 w-[15rem] lg:w-full"
              onClick={() => {
                setSelectedKey(item?.id || "")
                setQueryMarket((preV) => {
                  if (item?.id === "all") {
                    return { ...omit(preV, ["categoryId"]) }
                  } else {
                    return { ...preV, categoryId: item?.id || "" }
                  }
                })
              }}>
              {renderLabelTab(
                item?.name,
                selectedKey === item?.id ? `/img/market/White/${item?.iconWhite}` : `/img/market/Black/${item?.iconBlack}`,
                selectedKey === item?.id,
              )}
            </List.Item>
          )}
        />
        <div className="mx-5 mb-5 mt-0 lg:mt-5 lg:ml-0 w-auto md:w-full">
          <div className="h-full flex flex-col rounded-lg border border-solid border-[var(--secondary-20)">
            <div className="flex justify-between items-center border-b-[1px] boder-solid border-[var(--secondary-20)]">
              <h2 className="text-[var(--secondary-100)] font-bold text-lg lg:text-xl xl:text-2xl p-4">
                {find(dataCategories, { id: selectedKey as string })?.name || ""}
              </h2>
              {/* <div className="flex justify-end mx-2 md:mx-5 py-4">
              <button
                type="button"
                className="w-12 h-12 border border-[var(--secondary-20)] rounded-lg hover:text-[var(--primary--70)] hover:border-[var(--primary--70)] flex items-center justify-center mr-2">
                <Image
                  alt="filter"
                  src="/img/icon/filter.svg"
                  width={24}
                  height={14}
                />
              </button>
              <button
                type="button"
                className="w-12 h-12 border border-[var(--secondary-20)] rounded-lg hover:text-[var(--primary--70)] hover:border-[var(--primary--70)] flex items-center justify-center">
                <Image
                  alt="sort"
                  src="/img/icon/sort.svg"
                  width={24}
                  height={14}
                />
              </button>
            </div> */}
            </div>

            <LoadingResult
              isLoading={isLoading && !dataMarkets?.length}
              isShowResult={Boolean(dataMarkets?.length)}
              icon="/img/gif/Market.gif"
              result={
                <div className="overflow-y-auto">
                  <div className="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 gap-2 py-4 md:px-4">
                    {dataMarkets?.map((item: IMarketItems) => (
                      <CardItemMarket
                        keyProps={item?.id}
                        keyActive={activeButtons}
                        className="col-span-1"
                        type={"default"}
                        url={item?.web_url ? item?.web_url : `/market/${item?.id}`}
                        target={item?.web_url ? "_blank" : "_self"}
                        url_image={item?.picture1}
                        alt_image={item?.title}
                        category={item?.category?.name}
                        title={item?.title}
                        classNameTitle="text-[var(--market--title-color)]"
                        desc={item?.description}
                        location={item?.country}
                        buttonTopRight={buttonTopRight(item, "absolute top-[6px] right-[6px]")}
                        labelBottom={renderLabelBottom(item?.trade_type, "absolute bottom-0 left-0 right-0 py-2 mx-2")}
                      />
                    ))}
                  </div>
                </div>
              }
              contentNotFound={
                <NotFoundBox
                  className="!bg-[var(--secondary-10)] py-8 rounded-3xl"
                  backHome={false}
                  message={transMusic("we_found_nothing_here")}
                  slot={
                    <button
                      type="button"
                      onClick={() => {
                        router.push(`/market/create`)
                      }}
                      className="text-center inline-block w-full underline font-medium lg:text-lg">
                      {trans("become_first_upload_here")}
                    </button>
                  }
                />
              }
            />
            <LoadMoreInfinite
              isLoading={isLoading}
              isNextPage={isNextPage}
              hasNextPage={hasNextPage}
              fetchNextPage={fetchNextPage}
            />
          </div>
        </div>
      </div>
    </>
  )
}
