import { paginationNumber, sortArray, sortBy, useSearchParams } from "@/utils/format"
import { Link, router, usePage } from "@inertiajs/react"
import { Fragment, useState } from "react"
import Pagination from "./Pagination"
import SearchInput from "./SearchInput"
import { ButtonLabel, FilterModal, filterResetAction } from "./FilterCard"
import { useAtomValue } from "jotai"
import { filterAtom } from "@/atoms"
import { ModalButton } from "./WithModal"
import { useEffect } from "react"
import TableContentItem from "./TableContentItem"
import { useSidebar } from "./ui/sidebar"
import { ArrowUp, ArrowDown, InboxIcon, Table2, LayoutList } from "lucide-react"
import { cn } from "@/lib/utils"
import DropdownAction from "./Default/DropdownAction"
import { isMobile } from "react-device-detect"

function Table(props) {
  const { location, page } = usePage().props
  const { tableHeader, tableBody = [], tableAction = null, tableFooter = null, tableRender = null, headerSection = null } = props
  const { bottomLeftSection = null, bottomCenterSection = null, bottomRightSection = null } = props
  const { tablePage = null, children = null, headerCenterButton = null, headerLeftButton = null, headerRightButton = null } = props
  const { search = false, filter = false, filterOptions = null, maxWidth = null } = props
  const { addButton = true, addLink = `${page?.url}/create`, cardChecbox = true, isCardLoadMore = true, wrapperClassName = null } = props
  let { tdBodyClassName = "text-start whitespace-pre md:whitespace-normal" } = props
  let { trBodyClassName = "text-start" } = props

  const [isDomLoaded, setIsDomLoaded] = useState(false)

  let isTableView = !isMobile
  if (window?.localStorage?.getItem("isTableView")) {
    isTableView = window?.localStorage?.getItem("isTableView") == "true"
  }

  const [isTable, setIsTable] = useState(isTableView)

  useEffect(() => {
    setIsDomLoaded(true)
    if (window?.localStorage?.getItem("isTableView")) {
      setIsTable(window?.localStorage?.getItem("isTableView") == "true")
    }

    return () => { }
  }, [])

  useEffect(() => {
    if (window?.localStorage && window?.localStorage?.getItem("isTableView") != isTable) {
      window?.localStorage.setItem("isTableView", isTable)
    }

    return () => { }
  }, [isTable])

  const { params } = useSearchParams(location)

  const searchable = !!tableHeader ? tableHeader?.filter((header) => !!header?.isSearchable && !header?.isHidden) : null
  const filters = Object.keys(useAtomValue(filterAtom) ?? [])

  let isActiveFilter = false
  for (const filter of filters) {
    if (params.get(filter) && params.get(filter) != "") {
      isActiveFilter = true
      continue
    }
  }

  const [sort, setSort] = useState({
    by: null,
    asc: false,
  })

  const handleSortBy = (header) => {
    setSort((state) => ({
      ...state,
      by: header.value,
      asc: !state.asc,
    }))
    params.delete("sort")
    params.delete("sortDirection")
    router.visit(`?${params.toString()}`, {
      method: "get",
      preserveState: true,
      preserveScroll: true,
      async: false,
    })
  }

  const currentServerSort = params.get("sort")
  const currentServerDirection = params.get("sortDirection")

  const TableRender = tableRender
  const sidebar = useSidebar()

  return (
    <div
      className={wrapperClassName ?? `relative w-full min-h-[68dvh] flex flex-col items-center pt-2 ${maxWidth ?? "max-w-[calc(100vw-0.5rem)] sm:max-w-[calc(100vw-5rem)]"}`}
    >
      <div className="flex flex-col items-center lg:items-center justify-between w-full gap-4 md:flex-row">
        <div className={`order-2 md:order-1 ${!headerCenterButton ? "flex-1" : ""}`}>
          <div className="flex flex-wrap items-center gap-2 place-content-center md:place-content-start">
            {filter && filterOptions ? (
              <>
                <div className="m-1">
                  <ModalButton id={`modal_filter`} btnLabel={<ButtonLabel />} />
                </div>
                {isActiveFilter ? (
                  <button onClick={(e) => filterResetAction(e, location, filters)} className="btn btn-error btn-xs">
                    Hapus Filter
                  </button>
                ) : null}
              </>
            ) : null}
            {cardChecbox ? (
              <div className="flex items-center bg-white dark:bg-gray-800 rounded-lg p-1 border border-gray-200 dark:border-gray-700">
                <button
                  onClick={() => setIsTable(true)}
                  className={cn(
                    "p-1.5 rounded-md transition-all duration-200",
                    isTable
                      ? "bg-white dark:bg-gray-600 text-blue-600 dark:text-blue-400 shadow-sm ring-1 ring-black/5"
                      : "text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200"
                  )}
                  title="Tampilan Tabel"
                >
                  <Table2 className="w-4 h-4" />
                </button>
                <button
                  onClick={() => setIsTable(false)}
                  className={cn(
                    "p-1.5 rounded-md transition-all duration-200",
                    !isTable
                      ? "bg-white dark:bg-gray-600 text-blue-600 dark:text-blue-400 shadow-sm ring-1 ring-black/5"
                      : "text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200"
                  )}
                  title="Tampilan Card"
                >
                  <LayoutList className="w-4 h-4" />
                </button>
              </div>
            ) : null}
            {headerLeftButton && typeof headerLeftButton === "function" && (
              <div className="w-full md:max-w-[20rem]">
                {headerLeftButton()}
              </div>
            )}
          </div>
        </div>

        <div className="order-1 md:order-2 flex flex-col md:flex-row gap-2">
          {headerCenterButton && typeof headerCenterButton === "function" && headerCenterButton()}
        </div>

        <div className="order-3 flex flex-col sm:flex-row gap-2 items-center">
          {search ? <SearchInput searchable={searchable} /> : null}
          {addButton ? (
            <Link href={addLink} className="btn btn-primary w-max btn-sm text-white">
              <i className="fas fa-plus"></i>
              Tambah
            </Link>
          ) : null}
          {headerRightButton && typeof headerRightButton === "function" && headerRightButton()}
        </div>
      </div>

      {headerSection && typeof headerSection === "function" && headerSection()}

      {!!TableRender ? (
        <TableRender {...props} />
      ) : (
        <>
          {isTable ? (
            <div
              className={cn(
                "overflow-auto flex-1 max-h-[62dvh] sm:max-h-[calc(100vh-13.2rem)] mt-1",
                !sidebar?.open
                  ? "w-full max-w-[calc(100vw-0.25rem)] md:max-w-[calc(100vw-6rem)]"
                  : "w-full max-w-[calc(100vw-0.25rem)] md:max-w-[calc(100vw-19rem)]",
              )}
            >
              <table className={`table table-zebra table-pin-rows table-pin-cols relative border-[1.5px] ${tableHeightStyle}`}>
                <thead className="border-b-[1.5px]">
                  <tr className="">
                    {tableHeader.map((header, i) => {
                      if ("isDetail" in (header || {}) && header.isDetail === true) return null
                      if ("isHidden" in (header || {}) && header.isHidden === true) return null
                      const Tag = i === 0 ? "th" : "td"

                      let isSortable = true
                      if ("isSortable" in (header || {}) && header.isSortable === false) {
                        isSortable = false
                      }
                      const isClientSort = header?.isClientSort ?? false

                      const isClientSorted = sort.by === header.value
                      const isServerSorted = currentServerSort === header.value
                      const isSorted = isClientSorted || isServerSorted

                      let direction = null
                      if (isClientSorted) {
                        direction = sort.asc ? "asc" : "desc"
                      } else if (isServerSorted) {
                        direction = currentServerDirection || "asc"
                      }

                      return (
                        <Tag key={i} scope="col" className="text-start">
                          <button
                            onClick={() => (isSortable ? (!!isClientSort ? handleSortBy(header) : sortBy(header.value, router, params)) : null)}
                            className={cn(
                              "flex items-center gap-1 text-sm",
                              header?.headerClassName,
                              isSorted && isSortable ? "bg-primary text-gray-100 px-2 rounded-lg font-normal" : "",
                              !isSortable && "cursor-not-allowed",
                            )}
                            disabled={!isSortable}
                          >
                            {header.label}

                            {isSorted && isSortable && direction === "asc" && <ArrowUp className="h-4 w-4" />}
                            {isSorted && isSortable && direction === "desc" && <ArrowDown className="h-4 w-4" />}
                          </button>
                        </Tag>
                      )
                    })}
                  </tr>
                </thead>
                <tbody className="relative">
                  {!!children ? (
                    children
                  ) : tableBody.length == 0 ? (
                    <tr>
                      <td colSpan={tableHeader.length}>
                        <NoData />
                      </td>
                    </tr>
                  ) : (
                    <>
                      {tableBody.sort(sortArray(sort.by, sort.asc)).map((body, index) => {
                        let tdProps = { index, props, body, tableHeader, tdBodyClassName, trBodyClassName, tableAction }

                        return (
                          <tr key={index} className={trBodyClassName}>
                            <TableContent {...tdProps} />
                          </tr>
                        )
                      })}

                      {tableFooter &&
                        typeof tableFooter === "function" &&
                        tableFooter({ tableBody, tableHeader, defaultClassName: { tdBodyClassName, trBodyClassName } })}
                    </>
                  )}
                </tbody>
              </table>
            </div>
          ) : (
            <>
              <TableCard props={props} tableBody={tableBody} tableHeader={tableHeader} tableAction={tableAction} isCardLoadMore={isCardLoadMore} />
              {tableFooter &&
                typeof tableFooter === "function" &&
                tableFooter({ tableBody, tableHeader, defaultClassName: { tdBodyClassName, trBodyClassName }, isTable: false })}
            </>
          )}
        </>
      )
      }
      <div className="flex flex-col md:flex-row items-center justify-between w-full pt-4 pb-4 gap-4">
        {bottomLeftSection && typeof bottomLeftSection === "function" && (
          <div className="w-full md:w-auto">
            {bottomLeftSection({ tableBody, tableHeader, defaultClassName: { tdBodyClassName, trBodyClassName } })}
          </div>
        )}

        {bottomCenterSection && typeof bottomCenterSection === "function" && (
          <div className="w-full md:w-auto flex justify-center">
            {bottomCenterSection({ tableBody, tableHeader, defaultClassName: { tdBodyClassName, trBodyClassName } })}
          </div>
        )}

        {bottomRightSection && typeof bottomRightSection === "function" && (
          <div className="w-full md:w-auto flex justify-end">
            {bottomRightSection({ tableBody, tableHeader, defaultClassName: { tdBodyClassName, trBodyClassName } })}
          </div>
        )}

        {tablePage && (
          <div className="w-full md:w-auto md:ml-auto">
            <Pagination
              links={Array.isArray(tablePage) ? tablePage : tablePage?.links}
              meta={Array.isArray(tablePage) ? null : tablePage}
            />
          </div>
        )}
      </div>

      {filter && isDomLoaded ? <FilterModal options={filterOptions} /> : null}
    </div >
  )
}

export const TableContent = ({ props, body, tableHeader, tdBodyClassName, index, tableAction }) => {
  return (
    <Fragment>
      {tableHeader.map((header, i) => (
        <TableContentItem
          key={i}
          header={header}
          item={body}
          index={index}
          variant="table"
          className={tdBodyClassName}
          tableAction={tableAction}
          {...props}
        />
      ))}
    </Fragment>
  )
}

export const WithAction = (props) => {
  const { actionMenu, item, align = "left", isTable = true, btnClassName = null, variant = "shadcn" } = props
  const Tag = isTable ? "th" : "div"

  if (variant == "shadcn") return <DropdownAction Tag={Tag} {...props} />

  return (
    <Tag scope="row" className={`text-start ${isTable ? 'w-10' : ''}`}>
      <div className={`dropdown dropdown-${align}`}>
        <div tabIndex={0} role="button" className={btnClassName ?? "m-1 btn btn-ghost btn-sm"}>
          <i className="fas fa-ellipsis-vertical"></i>
        </div>
        <ul tabIndex={0} className="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-max">
          {actionMenu && typeof actionMenu === "function" && actionMenu(item)}
        </ul>
      </div>
    </Tag>
  )
}

export const NoData = () => {
  return (
    <div className="flex flex-col items-center gap-2 py-8">
      <InboxIcon className="w-10 h-10 opacity-40" />
      <p>Tidak ada data untuk ditampilkan</p>
    </div>
  )
}

export const TableCard = ({ props, tableBody, tableHeader, isLimitIndex = true, tableAction = null, isCardLoadMore = true }) => {
  if (tableBody?.length == 0) return <NoData />

  const { location, page } = usePage().props
  const { url } = useSearchParams(location)
  let pageData = page?.[page?.name]

  const [loadIndex, setLoadIndex] = useState(null)

  return (
    <div className={`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-4 my-4 w-full px-2 items-start`}>
      {tableBody.map((body, index) => {
        // Find special columns
        const titleColumn = tableHeader.find(h => h.value == 'name') ||
          tableHeader.find(h => h.value?.endsWith('name')) ||
          tableHeader.find(h => h.value?.endsWith('title')) ||
          tableHeader.find(h => h.isDefaultLabel) ||
          tableHeader.find(h => h.value?.endsWith('description')) ||
          tableHeader[1]
        const statusColumn = tableHeader.find(h => h.type === 'status')
        const numberingColumn = tableHeader.find(h => h.type === 'numbering')

        // Filter out columns already shown or hidden
        const contentColumns = tableHeader.filter(h =>
          h !== titleColumn &&
          h !== statusColumn &&
          h !== numberingColumn &&
          h.type !== 'action' &&
          !h.isHidden &&
          (!h.isDetail || (loadIndex === index)) // Show detail only if expanded
        )

        const isExpanded = loadIndex === index
        const hasHiddenDetails = tableHeader.some(h => h.isDetail)

        return (
          <div key={index} className="card bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 hover:shadow-md transition-shadow duration-200">
            <div className="card-body p-4 gap-3">
              {/* Header: Title & Action */}
              <div className="flex justify-between items-start gap-2">
                <div className="flex flex-col gap-1 w-full">
                  <div className="flex items-center justify-between w-full">
                    <span className="text-xs font-mono text-gray-400">
                      #{pageData ? paginationNumber(pageData, index) : index + 1}
                    </span>
                    {statusColumn && (
                      <div className="scale-90 origin-right">
                        <TableContentItem header={statusColumn} item={body} index={index} variant="card" />
                      </div>
                    )}
                  </div>

                  {titleColumn && (
                    <div className="font-semibold text-gray-900 dark:text-gray-100 text-base leading-tight">
                      <TableContentItem header={titleColumn} item={body} index={index} variant="card" />
                    </div>
                  )}
                </div>

                {tableAction && (
                  <div className="-mr-2 -mt-2">
                    <WithAction item={body} actionMenu={tableAction} align="end" isTable={false} />
                  </div>
                )}
              </div>

              <div className="divider my-0"></div>

              {/* Body: Grid of details */}
              <div className="grid grid-cols-1 gap-y-2 gap-x-4 text-sm">
                {contentColumns.map((header, i) => (
                  <div key={i} className={`flex flex-col ${header.wrapperClassName ?? ''} ${header.type === 'list' || header.type === 'html' ? 'col-span-2' : ''}`}>
                    <span className="text-xs text-gray-500 dark:text-gray-400 font-medium">{header.label}</span>
                    <div className="text-gray-700 dark:text-gray-300 min-h-[1.25rem]">
                      <TableContentItem header={header} item={body} index={index} variant="card" />
                    </div>
                  </div>
                ))}
              </div>

              {/* Footer: Expand Button if needed */}
              {hasHiddenDetails && isCardLoadMore && (
                <button
                  onClick={() => setLoadIndex(isExpanded ? null : index)}
                  className="w-full mt-2 py-1 text-xs text-center text-gray-500 hover:text-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 rounded transition-colors"
                >
                  {isExpanded ? (
                    <span className="flex items-center justify-center gap-1"><i className="fas fa-chevron-up"></i> Sembunyikan</span>
                  ) : (
                    <span className="flex items-center justify-center gap-1"><i className="fas fa-chevron-down"></i> Selengkapnya</span>
                  )}
                </button>
              )}
            </div>
          </div>
        )
      })}
    </div>
  )
}



export const tableHeightStyle = `
    [&_th]:px-2 [&_th]:py-1
    [&_td]:px-2 [&_td]:!py-[0px] [&_td]:!m-0 [&_td]:leading-none [&_td]:!min-h-0 [&_td]:!h-auto
    [&_tr]:!p-0 [&_tr]:!m-0 [&_tr]:!min-h-0 [&_tr]:!h-auto
  `

export default Table
