import { FileType, MemberType } from "@openchat/types"
import { DateUtils } from "@openchat/core"
import classNames from "classnames"
import { Fragment, useEffect, useRef, useState } from "react"
import { Document, Page } from "react-pdf"
import { Icon } from "../../../ui-component/icon/icon.component"
import { useModal } from "../../../ui-component/modal"
import { memoComponent } from "@openchat/ui"
import styles from "./message-attachment-pdf-viewer-modal.styles.module.css"
import { AppController } from "../../../app/app.globals.js"

export const MessageAttachmentPdfViewerModal = memoComponent(
  "MessageAttachmentPdfViewerModal",
  ({
    fileId,
    sender,
    date,
  }: {
    fileId: string
    sender: MemberType
    date: Date
  }) => {
    // ---------------------------------------------------------------------------
    // variables
    // ---------------------------------------------------------------------------

    const modal = useModal()
    const leftSideScrollRef = useRef<HTMLDivElement>(null)
    const rightSideScrollRef = useRef<HTMLDivElement>(null)

    const [pageIndex, setPageIndex] = useState(1)
    const [page, setPage] = useState(1)
    const [selectedIndex, setSelectedIndex] = useState(0)
    const [zoom, setZoom] = useState(1)
    const [file, setFile] = useState<FileType | null>(null)

    const dateTime = [
      date.getDate(),
      date.getMonth() + 1,
      date.getFullYear(),
    ].join("/")
    let hours = date.getHours()
    let amORpm = hours >= 12 ? "PM" : "AM"

    // ---------------------------------------------------------------------------
    // effects
    // ---------------------------------------------------------------------------

    useEffect(() => {
      loader()
    }, [fileId])

    useEffect(() => {
      if (!rightSideScrollRef.current || !leftSideScrollRef.current) return

      const handleScroll = () => {
        if (!rightSideScrollRef.current || !leftSideScrollRef.current) return
        const { scrollTop } = rightSideScrollRef.current

        const rightItemHeight =
          document.getElementsByClassName(styles.mainPage)[0].clientHeight + 50

        const leftItemHight =
          document.getElementsByClassName(styles.navPage)[0].clientHeight + 50

        const newIndex = Math.floor(scrollTop / rightItemHeight)

        const totalPages = Math.ceil(
          rightSideScrollRef.current.scrollHeight / rightItemHeight,
        )

        if (
          newIndex !== selectedIndex &&
          newIndex >= 0 &&
          newIndex < totalPages
        ) {
          setSelectedIndex(newIndex)
          setPageIndex(newIndex + 1)
          leftSideScrollRef.current.scrollTop =
            newIndex < totalPages / 2
              ? leftItemHight * newIndex
              : (rightItemHeight * newIndex) / 2
        } else {
          setSelectedIndex(newIndex)
          setPageIndex(newIndex + 1)
          leftSideScrollRef.current.scrollTop = newIndex * leftItemHight
        }
      }

      const handleWheelZoom = (event: WheelEvent) => {
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault()
          const newZoom = zoom + event.deltaY * -0.01
          if (newZoom > 0.5 && newZoom < 5) {
            setZoom(newZoom)
          }
        }
      }

      rightSideScrollRef.current.addEventListener("scroll", handleScroll)
      rightSideScrollRef.current.addEventListener("wheel", handleWheelZoom)

      return () => {
        if (rightSideScrollRef.current) {
          rightSideScrollRef.current.removeEventListener("scroll", handleScroll)
          rightSideScrollRef.current.removeEventListener(
            "wheel",
            handleWheelZoom,
          )
        }
      }
    }, [zoom])

    // ---------------------------------------------------------------------------
    // functions
    // ---------------------------------------------------------------------------

    async function loader() {
      const file = await AppController.file.getFromLocal({ id: fileId })
      setFile(file)
    }

    function handleItemClick(index: number) {
      setSelectedIndex(index)
      onScrollRightSideToIndex(index)
    }

    function onScrollRightSideToIndex(index: number) {
      if (!rightSideScrollRef.current || !leftSideScrollRef.current) return

      const itemHeight =
        document.getElementsByClassName(styles.mainPage)[0].clientHeight + 50
      const scrollTop = index * itemHeight
      rightSideScrollRef.current.scrollTop = scrollTop
    }

    // ---------------------------------------------------------------------------
    if (!file) return
    return (
      <div className={styles.wrapper}>
        <div className={styles.header}>
          <div className={styles.headerTitleWrap}>
            <p className={styles.pageCount}>{`PDF ${pageIndex} of ${page} `}</p>

            <div className={styles.senderNameWrap}>
              <strong className={styles.senderName}>{sender.name}</strong>
              <span className={styles.dateTime}>
                {` ${dateTime} at ${DateUtils.getMessageListItemDateTime(
                  date,
                )} ${amORpm}`}
              </span>
            </div>
          </div>

          <div>
            <Icon
              className={styles.ellipsisButton}
              name="fal fa-ellipsis-v"
              onClick={() => {}}
            />
            <Icon
              className={styles.crossButton}
              name="fal fa-times"
              onClick={() => modal.close()}
            />
          </div>
        </div>

        <div className={styles.container}>
          <nav className={styles.nav} ref={leftSideScrollRef}>
            <Document
              className={styles.navDocument}
              file={file.data}
              onLoadSuccess={({ numPages }) => setPage(numPages)}
            >
              {Array.from(Array(page).keys()).map((index) => (
                <Fragment key={`page${index + 1}`}>
                  <Page
                    className={classNames({
                      [styles.navPage]: true,
                      [styles.focused]: index === selectedIndex,
                    })}
                    onClick={() => handleItemClick(index)}
                    height={240}
                    width={165}
                    pageNumber={index + 1}
                  />
                  <>{index + 1}</>
                </Fragment>
              ))}
            </Document>
          </nav>
          <div className={styles.documentWrap} ref={rightSideScrollRef}>
            <div
              className={styles.mainDocument}
              style={
                zoom >= 2 && zoom <= 5
                  ? { width: "-webkit-fill-available" }
                  : {}
              }
            >
              <Document
                file={file.data}
                onLoadSuccess={({ numPages }) => setPage(numPages)}
              >
                {Array.from(Array(page).keys()).map((index) => (
                  <Fragment key={`page${index + 1}`}>
                    <Page
                      className={styles.mainPage}
                      height={545}
                      width={373}
                      pageNumber={index + 1}
                      scale={zoom}
                    />
                  </Fragment>
                ))}
              </Document>
            </div>
          </div>
        </div>
        <div className={styles.footer}>
          <Icon className={styles.icon} name="fal fa-cloud-download" />
          <div>
            <Icon
              className={styles.icon}
              name="fal fa-search-plus"
              onClick={() => {
                if (zoom > 4) return
                setZoom((prevZoom) => prevZoom * 1.2)
              }}
            />
            <Icon
              className={styles.icon}
              name="fal fa-search-minus"
              onClick={() => {
                if (zoom < 0.5) return
                setZoom((prevZoom) => prevZoom / 1.2)
              }}
            />
            <Icon
              className={styles.icon}
              name="fal fa-undo"
              onClick={() => setZoom(1)}
            />
          </div>
        </div>
      </div>
    )
  },
)
please convert it to react native