"use client"

import React, { useCallback, useEffect, useMemo, useState } from "react"
import { Form, Table, Modal, Checkbox } from "antd"
import classNames from "classnames"
import type { MenuProps } from "antd"
import { useTranslations } from "next-intl"
import { find, flattenDeep, isEmpty, omitBy } from "lodash"
import { useRecoilValue } from "recoil"
import { contactOptions } from "@/config/constant"
import { typeContactState } from "@/recoil"
import MyContactInfo from "./MyContactInfo"
import { RenderMyContactStatus, useOpenChat } from "@component/Contact/Common"
import { DropDownMenu, CustomDropDownMenuCss } from "@/component/Common/DropDownMenu"
import { renderTooltipText } from "@/component/Common/TooltipText"
import { useDeleteContact, useDeleteMultipleContact, useGetContactList } from "@/hook/useContacts"
import dayjs from "dayjs"
import { IContacts, IContactsQuery } from "@/type/Contacts"
import { renderLabelItem } from "@component/Common/LabelItem"
import Image from "next/image"

import { useSearchParams } from "next/navigation"
import { usePathname, useRouter } from "@/i18n/routing"
import { useNotificationContext } from "@/component/Layout/NotificationContext"
import { LoadingBox } from "@/component/Common/LoadingBox"
import HeaderBreadcrumb from "@/component/Layout/HeaderBreadcrumb"
import SearchBox from "@/component/Layout/SearchBox"
import { LoadMoreInfinite } from "@/component/Common/LoadMoreInfinite"
import { useQueryClient } from "@tanstack/react-query"
import { useAddFriendCometChat } from "@/hook/useChat"

const MyContactList = () => {
  const [formRef] = Form.useForm()
  const options = contactOptions()
  const router = useRouter()
  const pathname = usePathname()
  const searchParams = useSearchParams()
  const oldSearch = Object.fromEntries(searchParams.entries())
  const optionHeader = useRecoilValue<string | number>(typeContactState)
  const [modal, modalContextHolder] = Modal.useModal()
  const { notify } = useNotificationContext()
  const openChat = useOpenChat()
  const queryClient = useQueryClient()

  const trans = useTranslations("contact")
  const transBook = useTranslations("book")
  const transButton = useTranslations("button")
  const transMessage = useTranslations("message")
  const transGeneral = useTranslations("general")

  const [keyword, setKeyword] = useState(searchParams.get("search") || "")
  const [inforContact, setInforContact] = useState<IContacts>({})
  const [openDrawer, setOpenDrawer] = useState<boolean>(false)
  const [loading, setLoading] = useState<boolean>(true)
  const [widthCol, setWidthCol] = useState<number>(238)
  const [query, setQuery] = useState<IContactsQuery>({})
  const [isNextPage, setIsNextPage] = useState(true)
  const [selectedRowKeys, setSelectedRowKeys] = useState<any>([])

  const deleteContact = useDeleteContact()
  const DeleteMultipleContact = useDeleteMultipleContact()
  const { data, isLoading, fetchNextPage, hasNextPage, isFetchingNextPage } = useGetContactList(query)
  const addFriendCometChat = useAddFriendCometChat()

  const dataContacts = useMemo(() => {
    if (flattenDeep(data?.pages.map((e: any) => e.data!)).length > 0) {
      const newContacts = flattenDeep(data?.pages.map((e: any) => e?.data?.data?.contacts)) || []
      const sortContact = newContacts?.sort((a: any, b: any) => a.name.localeCompare(b.name))
      return sortContact
    }
    return []
  }, [data?.pages])

  const dataContactsLength = dataContacts?.length
  const isAllSelected = selectedRowKeys?.length === dataContactsLength
  const isSomeSelected = selectedRowKeys?.length > 0 && !isAllSelected
  const isEmptySelectRowKey = isEmpty(selectedRowKeys)

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

  useEffect(() => {
    handleSearchKeyword(searchParams.get("search") || "")
    setKeyword(searchParams.get("search") || "")
  }, [searchParams])

  useEffect(() => {
    const updateTabPosition = () => {
      setWidthCol(window.innerWidth >= 768 ? 238 : 158)
    }
    updateTabPosition()
    window.addEventListener("resize", updateTabPosition)

    return () => {
      window.removeEventListener("resize", updateTabPosition)
    }
  }, [])

  const showLoading = () => {
    setOpenDrawer(true)
    setLoading(true)

    // Simple loading mock. You should add cleanup logic in real world.
    setTimeout(() => {
      setLoading(false)
    }, 1000)
  }

  const countData = useMemo(() => dataContacts?.length, [dataContacts?.length])

  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 handleSearchKeyword = (keyword: string) => {
    if (keyword && keyword?.length >= 3) {
      const updatedQuery = { ...oldSearch, search: keyword?.trim() }
      const cleanedObj = omitBy(updatedQuery, (value) => value === null || value === undefined || value === "")

      setQuery(cleanedObj)
      updateSearchQuery(cleanedObj)
    }
    if (keyword === "" && query?.search) {
      setQuery({})
      updateSearchQuery({})
    }
  }

  useEffect(() => {
    if (!isEmpty(Object.fromEntries(searchParams.entries()))) {
      const updatedQuery = { ...oldSearch } as IContactsQuery
      setQuery(updatedQuery)
      updateSearchQuery(updatedQuery)

      if (searchParams.has("search")) {
        handleSearchKeyword(oldSearch?.search)
      }
    }
  }, [])

  const handleDeleteContact = (contact?: IContacts) => {
    deleteContact
      .mutateAsync(contact?.uid || "")
      .then((res: any) => {
        if (res?.status === 200) {
          notify({
            type: "success",
            message: transMessage("congratulation"),
            description: transGeneral("deleted_successfully"),
          })

          if (openDrawer) {
            setOpenDrawer(false)
          }
        }
        queryClient.invalidateQueries({ queryKey: ["contacts.infinite_get_list", query] })
      })
      .catch((errors) => {
        notify({
          type: "error",
          message: transMessage("something_wrong"),
          description: errors?.response?.data.msgs || transMessage("fail"),
        })
      })
  }

  const handleDeleteMultipleContact = (arrId?: string[]) => {
    DeleteMultipleContact.mutateAsync({ ids: arrId || [] })
      .then((res: any) => {
        if (res?.status === 200) {
          notify({
            type: "success",
            message: transMessage("congratulation"),
            description: res?.data?.msg || transGeneral("deleted_successfully"),
          })
          setSelectedRowKeys([])
          queryClient.invalidateQueries({ queryKey: ["contacts.infinite_get_list", query] })
        }
      })
      .catch((errors) => {
        notify({
          type: "error",
          message: transMessage("something_wrong"),
          description: errors?.response?.data?.msgs || transMessage("fail"),
        })
      })
  }

  const confirmDelete = (contact?: IContacts) => {
    modal.confirm({
      title: transGeneral("confirm_delete"),
      okText: transButton("ok"),
      cancelText: transButton("cancel"),
      onOk() {
        handleDeleteContact(contact)
      },
    })
  }

  const confirmDeleteMultiple = (arrId: string[]) => {
    modal.confirm({
      title: transGeneral("confirm_delete"),
      okText: transButton("ok"),
      cancelText: transButton("cancel"),
      onOk() {
        handleDeleteMultipleContact(arrId)
      },
    })
  }

  const handleSelectAll = (checked: any) => {
    setSelectedRowKeys(checked ? dataContacts?.map((item) => item.uid) : [])
  }

  const handleOpenChange = (inforContact: any) => {
    setInforContact(inforContact)
  }

  const handleAddFriend = (uid: string) => {
    addFriendCometChat
      .mutateAsync(String(uid))
      .then((res: any) => {
        notify({
          type: "success",
          message: transMessage("congratulation"),
          description: res?.data?.msg || trans("add_friend_successfully"),
        })
      })
      .catch((errors) => {
        console.log("errors", errors?.response?.data?.error?.message)

        notify({
          type: "error",
          message: transMessage("something_wrong"),
          description: errors?.response?.data?.error?.message || transMessage("fail"),
        })
      })
  }

  const buttonAction = (record: IContacts) => {
    const items: MenuProps["items"] = [
      {
        label: renderLabelItem(transBook("go_detail"), "/img/icon/information_circle_outline.svg", "information_circle_outline"),
        key: "0",
        onClick: () => {
          showLoading()
        },
      },
      {
        label: renderLabelItem(trans("send_message"), "/img/icon/message_black.svg", "send_message"),
        key: "1",
        onClick: () => openChat(String(record?.uid) || ""),
      },
      {
        label: renderLabelItem(trans("add_friend"), "/img/icon/plus.svg", "add_friend"),
        key: "2",
        onClick: () => handleAddFriend(String(record?.uid)),
      },
      {
        label: renderLabelItem(transBook("delete"), "/img/icon/trash_outline.svg", "trash_outline"),
        key: "3",
        onClick: () => confirmDelete(record),
      },
    ]
    return (
      <DropDownMenu
        menu={{ items, className: classNames("", CustomDropDownMenuCss) }}
        onOpenChange={() => {
          handleOpenChange(record)
        }}
      />
    )
  }

  const columns: any = useMemo(
    () => [
      {
        title: "Contacts",
        dataIndex: "alpha",
        key: "alpha",
        fixed: "left",
        className: "!p-1",
        width: widthCol,
        ellipsis: {
          showTitle: false,
        },
        render: (_: string, record: any, index: number) => {
          const keyAlpha =
            index === 0 || dataContacts[index - 1]?.name?.slice(0, 1)?.toLocaleUpperCase() !== record?.name?.slice(0, 1)?.toLocaleUpperCase() ? (
              <div className="mr-2 px-[13px] py-2.5 w-[37px] h-[2.625rem] bg-[var(--secondary-100)] text-white uppercase text-center text-base leading-[22px] font-semibold">
                {record?.name?.slice(0, 1)}
              </div>
            ) : (
              ""
            )

          return (
            <div className="flex">
              {keyAlpha}
              {renderTooltipText(record?.name, "!bg-[var(--primary--20)] !text-[var(--primary--90)]", `flex-1 ${(!keyAlpha && "ml-11") || ""}`)}
            </div>
          )
        },
      },
      {
        title: "Status",
        dataIndex: "status",
        key: "status",
        align: "center",
        className: "!p-1",
        width: 108,
        render: (status: string) => RenderMyContactStatus(status, `${status ? "bg-[var(--success-10)]" : "bg-[var(--danger-10)]"}`),
      },
      {
        title: "Date Added",
        dataIndex: "created_at",
        key: "created_at",
        align: "center",
        className: "!p-1",
        width: 208,
        ellipsis: {
          showTitle: false,
        },
        render: (created_at: number) => {
          return created_at ? renderTooltipText(dayjs.unix(created_at).format("MMM DD, YYYY"), "!font-light bg-[var(--secondary-10)]") : "--"
        },
      },
      Table.SELECTION_COLUMN,
      {
        key: "action",
        fixed: "right",
        className: "!p-1",
        width: 44,
        render: (record: IContacts) => {
          return (
            <div className="flex gap-3">
              <Checkbox
                checked={selectedRowKeys.includes(record.uid)}
                onChange={(e) => {
                  const checked = e.target.checked
                  setSelectedRowKeys((prev: any) => (checked ? [...prev, record.uid] : prev.filter((key: any) => key !== record.uid)))
                }}
              />
              {buttonAction(record)}
            </div>
          )
        },
      },
    ],
    [dataContacts, widthCol, selectedRowKeys],
  )

  return (
    <div className="h-full flex flex-col">
      <HeaderBreadcrumb
        showButton={false}
        items={[
          {
            aria_label: find(options, { value: optionHeader as string })?.label || "",
            href: "#",
            title: find(options, { value: optionHeader as string })?.label || "",
          },
        ]}
        className="flex-col !items-start lg:flex-row lg:items-center"
        slot={
          <SearchBox
            value={keyword}
            onSearch={handleSearchKeyword}
            onChange={setKeyword}
            placeholder={trans("search_contact_here")}
            className="h-12"
            classInput="!h-12 lg:!w-56 xl:!w-56"
            classButton="!h-12 md:!pl-2"
          />
        }
      />
      <div className="px-5 py-6 text-[var(--secondary-60)] text-base leading-[22px] font-normal flex gap-4 justify-between">
        <p>{`${trans("we_found")} ${countData || 0} ${countData > 1 ? trans("contacts") : trans("contact")}`}</p>
        <div className="flex gap-5">
          {Boolean(dataContactsLength) && (
            <>
              <Checkbox
                className="flex-row-reverse !items-center"
                indeterminate={isSomeSelected}
                checked={isAllSelected}
                onChange={(e) => handleSelectAll(e.target.checked)}>
                {transGeneral("select_all")}
              </Checkbox>

              <button
                disabled={isEmptySelectRowKey}
                type="button"
                onClick={() => {
                  confirmDeleteMultiple(selectedRowKeys)
                }}
                className={`group bg-[var(--secondary-20)] inline-flex justify-center items-center rounded w-8 h-8 ${
                  isEmptySelectRowKey ? "" : "hover:bg-[var(--primary--70)]"
                }`}>
                <Image
                  src="/img/icon/trash_outline.svg"
                  alt="share"
                  width={24}
                  height={24}
                  className={`${isEmptySelectRowKey ? "" : "group-hover:hidden"}`}
                />
                <Image
                  src="/img/icon/trash_outline_white.svg"
                  alt="share"
                  width={24}
                  height={24}
                  className={`hidden ${isEmptySelectRowKey ? "" : "group-hover:block"}`}
                />
              </button>
            </>
          )}
        </div>
      </div>
      <div className="grow overflow-y-auto rounded-b-lg">
        {isLoading ? (
          <LoadingBox icon="/img/gif/Contact.gif" />
        ) : (
          <Table
            rowKey={"uid"}
            columns={columns}
            dataSource={dataContacts}
            pagination={false}
            loading={isFetchingNextPage || isLoading || deleteContact?.isPending || DeleteMultipleContact?.isPending}
            rowSelection={{
              selectedRowKeys,
              onChange: setSelectedRowKeys,
              columnWidth: 0,
            }}
          />
        )}

        <LoadMoreInfinite
          isLoading={isLoading}
          isNextPage={isNextPage}
          hasNextPage={hasNextPage}
          fetchNextPage={fetchNextPage}
        />
      </div>

      <MyContactInfo
        formRef={formRef}
        open={openDrawer}
        setOpen={setOpenDrawer}
        loading={loading}
        inforContact={inforContact}
        confirmDelete={confirmDelete}
      />
      {modalContextHolder}
    </div>
  )
}

export default MyContactList
