"use client"

import { find, isEmpty } from "lodash"
import { useRecoilValue } from "recoil"
import { useCallback, useEffect, useRef, useState } from "react"
import { useSearchParams } from "next/navigation"
import { usePathname, useRouter } from "@/i18n/routing"
import dayjs from "dayjs"
import customParseFormat from "dayjs/plugin/customParseFormat"

import HeaderCalendarPage from "./HeaderCalendarPage"
import { Calendar } from "./Calendar"
import { calendarOptions } from "@/config/constant"
import { typeCalendarState } from "@/recoil"
import { useDeleteEventCalendar, useGetEvents } from "@/hook/useCalendar"
import { ICalendarEventQueryType } from "@/type/Calendar"
import { LoadingBox } from "@component/Common/LoadingBox"
import { useNotificationContext } from "@component/Layout/NotificationContext"
import { useTranslations } from "next-intl"
import { Modal } from "antd"

dayjs.extend(customParseFormat)

type calendarRef = null | {
  _onGotoDate: (date: string) => void
}

export default function ContentCalendar() {
  const searchParams = useSearchParams()
  const pathname = usePathname()
  const options = calendarOptions()
  const router = useRouter()
  const optionHeader = useRecoilValue(typeCalendarState)
  const oldSearch = Object.fromEntries(searchParams.entries())
  const CalendarRef = useRef<calendarRef>(null)
  const dateCurrent = dayjs()
  const firstDayOfMonthUnix = dateCurrent.startOf("month").unix()
  const lastDayOfMonthUnix = dateCurrent.endOf("month").unix()
  const defaultQuery = { startDate: firstDayOfMonthUnix, endDate: lastDayOfMonthUnix }
  const { notify } = useNotificationContext()
  const [modal, modalContextHolder] = Modal.useModal()

  const transMessage = useTranslations("message")
  const transButton = useTranslations("button")
  const transGeneral = useTranslations("general")

  const [query, setQuery] = useState<ICalendarEventQueryType>(defaultQuery)
  const [searchValue, setSearchValue] = useState(searchParams.get("searchTitle") || "")
  const [isSearch, setIsSearch] = useState(false)

  const { data: dataEvents, isLoading, refetch } = useGetEvents(query)
  const deleteEventCalendar = useDeleteEventCalendar()

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

      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(`?${params.toString()}`, { scroll: false })
    },
    [searchParams, pathname, query],
  )

  const handleFilter = (keyword: string) => {
    if (keyword?.length >= 3) {
      const updatedQuery = { ...(keyword?.length >= 3 && { searchTitle: keyword }) } as ICalendarEventQueryType
      setQuery(updatedQuery)
      updateSearchQuery(updatedQuery)
    } else if (keyword.trim() === "") {
      setQuery(defaultQuery)
      updateSearchQuery({ searchTitle: "" })
    } else {
      setIsSearch(true)
      notify({
        type: "error",
        message: transMessage("something_wrong"),
        description: transMessage("search_value_must_3_more"),
      })
      setTimeout(() => {
        setIsSearch(false)
      }, 500)
    }
  }

  const formatStartEnd = (date: any, type: "startOf" | "endOf", value?: string): string => {
    const baseDate = dayjs.unix(date)

    if (value && baseDate) {
      // const [hour, minute] = value.split(":").map(Number)
      // return baseDate.hour(hour).minute(minute).second(0).format("YYYY-MM-DDTHH:mm:ss")
      
      const time = dayjs(value, "hh:mm A")
      if (time.isValid()) {
        return baseDate.hour(time.hour()).minute(time.minute()).second(0).format("YYYY-MM-DDTHH:mm:ss")
      }
      // return baseDate.hour(time.hour()).format("YYYY-MM-DDTHH:mm:ss") 
      throw new Error("Invalid time format")
    }

    return baseDate[type]("day").format("YYYY-MM-DDTHH:mm:ss")
  }

  useEffect(() => {
    if (query?.searchTitle && !isEmpty(dataEvents?.data?.events)) {
      const startDate = dataEvents?.data?.events?.[0]
      CalendarRef.current?._onGotoDate(formatStartEnd(Number(startDate?.date), "startOf", startDate?.time_from))
    }
    if (!query?.searchTitle && query?.startDate) {
      const firstDayOfMonth = dayjs
        .unix(Number(query?.startDate))
        .startOf("month")
        .format("YYYY-MM-DDTHH:mm:ss")
      CalendarRef.current?._onGotoDate(firstDayOfMonth)
    }
  }, [query, dataEvents?.data?.events])

  useEffect(() => {
    if (searchParams.has("searchTitle")) {
      setSearchValue(oldSearch?.searchTitle)
      setQuery({ searchTitle: oldSearch?.searchTitle })
    }
  }, [])

  useEffect(() => {
    setQuery(defaultQuery)
  }, [optionHeader])

  const handleDeleteEventCalendar = (id: number) => {
    deleteEventCalendar
      .mutateAsync(id)
      .then((res: any) => {
        if (res?.status === 200) {
          notify({
            type: "success",
            message: transMessage("congratulation"),
            description: transGeneral("deleted_successfully"),
          })
          refetch()
        }
      })
      .catch((errors) => {
        notify({
          type: "error",
          message: transMessage("something_wrong"),
          description: errors?.response?.data.msgs || transMessage("fail"),
        })
      })
  }

  const confirmDelete = (id: number) => {
    modal.confirm({
      title: transGeneral("confirm_delete"),
      okText: transButton("ok"),
      cancelText: transButton("cancel"),
      onOk() {
        handleDeleteEventCalendar(id)
      },
    })
  }

  return (
    <div className="border border-[var(--secondary-20)] rounded-lg flex flex-col h-full">
      <HeaderCalendarPage
        title={find(options, { value: optionHeader as string })?.title || ""}
        onSearch={handleFilter}
        value={searchValue}
        disabled={isSearch}
      />
      {isLoading ? (
        <LoadingBox icon="/img/gif/Calendar.gif" />
      ) : (
        <Calendar
          dataEvents={dataEvents}
          ref={CalendarRef}
          formatStartEnd={formatStartEnd}
          setQuery={setQuery}
          query={query}
          confirmDelete={confirmDelete}
        />
      )}
      {modalContextHolder}
    </div>
  )
}
