"use client"

import {useEffect, useMemo, useRef, useState} from "react"
import {assets} from "../../assets"
import {ImageView} from "../../atoms"
import {IAction, PaginationType, TableHeaderProps, TableProps} from "../../props"
import {MAX_TABLE_ITEMS} from "../../utils"
import styles from "./styles.module.sass"

export const Table = <T extends {id?: string; action?: IAction[]}>({
  tableHeaders = [],
  tableItems = [],
  wrapperClass: className = "",
  maxItems = MAX_TABLE_ITEMS,
}: TableProps<T>) => {
  const [curPage, setCurPage] = useState<number>(1)

  // To Filter the TABLE Item's KEYS
  const rowKeys = useMemo(() => tableHeaders.map((item: {rowKey: string}) => item.rowKey), [tableHeaders])

  const tableCells: T[] = tableItems || []

  const tableCurrentItems = useMemo(
    () => (maxItems ? tableCells.slice((curPage - 1) * maxItems, curPage * maxItems) : tableCells),
    [curPage, tableItems]
  )

  const totalItems = tableCells.length

  const tableContainerRef = useRef<HTMLDivElement | null>(null)

  useEffect(() => {
    const handleScroll = () => {
      if (tableContainerRef.current) {
        const {scrollTop, scrollLeft} = tableContainerRef.current
        const firstCell = tableContainerRef.current.querySelector("th:first-child, td:first-child") as HTMLElement

        // For vertical scrolling
        if (scrollTop > 0) {
          firstCell.style.zIndex = "0" // Scroll is vertical, set z-index to 0
        } else {
          firstCell.style.zIndex = "1" // Scroll is not vertical, set z-index to 1
        }

        // For horizontal scrolling
        if (scrollLeft > 0) {
          firstCell.style.zIndex = "2" // Scroll is horizontal, set z-index to 2
        }
      }
    }

    tableContainerRef?.current?.addEventListener("scroll", handleScroll)
    return () => {
      tableContainerRef?.current?.removeEventListener("scroll", handleScroll)
    }
  }, [])

  const totalPages = Array.from(
    {
      length: Math.ceil(maxItems ? totalItems / maxItems : 1),
    },
    (_, i) => i + 1
  )

  const pageCount = totalPages.length

  useEffect(() => {
    if (pageCount < curPage) setCurPage(pageCount || 1)
  }, [totalItems])

  const renderHeader = ({title}: TableHeaderProps) => (
    <th className={`${styles.custom_th} semi-bold`} key={title}>
      {title}
    </th>
  )

  const visiblePages = useMemo(() => {
    let pages = totalPages
    if (pageCount <= 4) pages = totalPages
    else if (curPage <= 2) pages = totalPages.slice(0, 4)
    else if (pageCount - curPage <= 2) pages = totalPages.slice(pageCount - 4, pageCount)
    else pages = totalPages.slice(curPage - 2, curPage + 2)

    return pages
  }, [curPage, totalPages])

  const pagesArr = [
    <ImageView key="left" src={assets?.ic_black_arrow} imgSize={24} alt="prev" wrapperClass={styles.arrow_left} />,
    ...visiblePages,
    <ImageView key="right" src={assets?.ic_black_arrow} imgSize={24} alt="next" wrapperClass={styles.arrow_right} />,
  ]

  const onClickPage = (page: PaginationType) => {
    if (page === pagesArr[0] && curPage > 1) setCurPage(curPage - 1)
    else if (page === pagesArr[pagesArr.length - 1] && curPage < pageCount) setCurPage(curPage + 1)
    else if (typeof page === "number") setCurPage(page)
  }

  const renderAction = ({label, action, onClick}: IAction, index: number) => (
    <section className={`${styles.edit} flex`} onClick={onClick} key={index}>
      <ImageView
        src={
          action === "block"
            ? assets.ic_view
            : action === "edit"
              ? assets.ic_edit
              : action === "delete"
                ? assets.ic_delete
                : assets.ic_view
        }
        alt="edit-icon"
        imgSize={20}
      />
      {label}
    </section>
  )

  // Rendering Table's Cell
  const renderCell = (item: T, cell: string | number, position: number) => (
    <td key={position} className={styles.custom_td}>
      {cell !== "action" ? (
        item[cell]
      ) : (
        <section className={`${styles.action_wrapper} flex`}>
          <ImageView src={assets.ic_more} imgSize={24} alt="more-icon" wrapperClass={styles.more_icon} />
          <section className={styles.action_card}>{item[cell]?.map(renderAction)}</section>
        </section>
      )}
    </td>
  )

  const renderRow = (item: T, index: number) => (
    <tr key={index} className={styles.custom_tr}>
      {rowKeys.map(renderCell.bind(null, item))}
    </tr>
  )

  // Rendering Table's Pagination
  const renderPage = (page: PaginationType, index: number) => (
    <li
      className={
        curPage === page
          ? `${styles.selected_page} flex`
          : (curPage === 1 && page === pagesArr[0]) || (curPage === pageCount && page === pagesArr[pagesArr.length - 1])
            ? `${styles.disabled_page}`
            : `${styles.page} flex`
      }
      key={index}
      onClick={onClickPage.bind(null, page)}>
      {page}
    </li>
  )

  const tableCount = tableCells?.length
  const from = maxItems ? (curPage - 1) * maxItems + 1 : 1
  const to = maxItems ? Math.min(curPage * maxItems, tableCount) : tableCount
  const displayedItems = maxItems ? (curPage === 1 ? Math.min(maxItems, tableCount) : maxItems) : tableCount
  return (
    <div ref={tableContainerRef} className={`${className} ${styles.table_container}`}>
      <table className={styles.custom_table}>
        <thead className={styles.custom_thead}>
          <tr className={styles.title}>{tableHeaders.map(renderHeader)}</tr>
        </thead>

        <tbody>{tableCurrentItems.map(renderRow)}</tbody>
      </table>
      {totalItems === 0 && <h4 className={styles.no_data_placeholder}>No Data Found!</h4>}
      {!!maxItems && (
        <section className={`${styles.page_wrapper} flex-sb-center`}>
          <p className={styles.table_bottom}>
            Displaying
            <small className={styles.count}>
              {curPage === 1
                ? displayedItems
                : `${from} 
                  - ${to}
                    `}
            </small>
            of {totalItems} items
          </p>
          <section className={`flex ${styles.page_count_wrapper}`}>
            <ul className={`${styles.page_navigate_wrapper} flex`}>{pagesArr.map(renderPage)}</ul>
            <section className={`flex ${styles.count_wrapper}`}>
              <small className={styles.active_page}>{curPage}</small>
              <small>of {pageCount} Pages</small>
            </section>
          </section>
        </section>
      )}
    </div>
  )
}
