import { currency, dateFormat, isNumber, paginationNumber, sortBy, useSearchParams } from "@/utlis/format"
import { router, usePage } from "@inertiajs/react"
import { Fragment, useState } from "react"
import Pagination from "./Pagination"
import useLang from "@/utlis/useLang"
import useStatus, { useStatusLabel } from "@/utlis/useStatus"
import SearchInput from "./SearchInput"
import { ButtonLabel, FilterModal, filterResetAction } from "./FilterCard"
import { useAtom, useAtomValue } from "jotai"
import { filterAtom, showModalAtom } from "@/atoms"
import { ModalButton } from "./WithModal"
import { useEffect } from "react"
import DetailModalItem from "./Default/DetailModalItem"
import { isMobile } from "react-device-detect"

function Table(props) {
  const { tableHeader, tableBody = [], tableAction = null, tableFooter = null, tableRender = null } = props
  const { tablePage = null, children = null, headerButton = null, headerLeftButton = null } = props
  const { search = false, filter = false, filterOptions = 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)
    setIsTable(window?.localStorage?.getItem("isTableView") == "true")

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

  useEffect(() => {

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

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


  const { location } = usePage().props
  const { params } = useSearchParams(location)

  const searchable = !!tableHeader ? tableHeader?.filter((header) => !!header?.isSearchable) : 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 TableRender = tableRender;

  return (
    <div className="relative w-full min-h-[68dvh] flex flex-col items-center pt-2 max-w-[97dvw] sm:max-w-[93dvw] md:max-w-[100dvw] overflow-hidden">
      <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 ${!headerButton ? '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}

            {headerLeftButton && typeof headerLeftButton === "function" && headerLeftButton()}
          </div>
        </div>

        <div className="order-1 md:order-2 flex flex-col md:flex-row gap-2">
          {headerButton && typeof headerButton === "function" && headerButton()}
        </div>
        {search ? (
          <div className="order-3">
            <SearchInput searchable={searchable} />
          </div>
        ) : null}
      </div>

      <div className="form-control mr-auto">
        <label className="label cursor-pointer">
          <input type="checkbox" checked={isTable} onChange={(e) => setIsTable(e.target.checked)} className="checkbox checkbox-sm" />
          <span className="label-text pl-2">Tampilan Tabel</span>
        </label>
      </div>

      {isTable ? (
        <div className="w-full max-w-[99vw] md:max-w-[95vw] overflow-auto flex-1 max-h-[62dvh] sm:max-h-[75vh] md:max-h-[77vh]">
          {!!TableRender ? <TableRender {...props} /> : (
            <table className={`table table-zebra table-pin-rows table-pin-cols relative ${tableHeightStyle}`}>
              <thead className="">
                <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
                    }

                    return (
                      <Tag key={i} scope="col" className="text-start">
                        <button
                          onClick={() => isSortable ? sortBy(header.value, router, params) : null}
                          className={`${header?.headerClassName} ${params.get("sort") != header.value ? "" : "bg-primary text-gray-100 px-2 rounded-lg font-normal "} text-sm`}
                        >
                          {header.label}
                        </button>
                      </Tag>
                    )
                  })}
                </tr>
              </thead>
              <tbody className="relative">
                {!!children ? (
                  children
                ) : tableBody.length == 0 ? (
                  <tr>
                    <td colSpan={12} className="!py-8 text-center">
                      <p>Belum ada data yang dapat ditampilkan</p>
                    </td>
                  </tr>
                ) : (
                  <>
                    {tableBody.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} />
      )}
      <div className="flex items-center justify-end w-full pt-2 pb-4">
        {!tablePage ? null : (
          <ul className="flex list-style-none">
            <Pagination links={tablePage} />
          </ul>
        )}
      </div>

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

export const TableContent = ({ props, body, tableHeader, tdBodyClassName, trBodyClassName, index, tableAction }) => {
  const [show, setShow] = useAtom(showModalAtom)

  return (
    <Fragment>
      {tableHeader.map((header, i) => {
        if ("isDetail" in (header || {}) && header.isDetail === true) return null
        if ("isHidden" in (header || {}) && header.isHidden === true) return null

        let isModalDetail = false
        if ("isModalDetail" in (header || {}) && header.isModalDetail === true) {
          isModalDetail = true
        }

        let headerValue = header?.value?.split(".")
        let value = headerValue?.reduce((acc, key) => acc?.[key], body)

        if (!value) {
          value = ""
        }

        if (!!header?.prefix && header?.type != 'status') {
          let prefix = header?.prefix
          if (!prefix.endsWith(".")) {
            prefix += "."
          }

          value = `${prefix ?? ""}${value}`
        }
        if (!!header?.valueLabel && !!value) {
          value = header?.valueLabel.toString().replaceAll("[value]", value)
        }

        if (!value && !!header?.defaultValue) {
          value = header?.defaultValue
        }

        if (header?.custom && typeof header?.custom === "function") {
          return header?.custom({ data: body, key: i, header, defaultClassName: { tdBodyClassName, trBodyClassName } })
        }

        if (header.type == "numbering") {
          return (
            <th key={i} scope="row" className="text-start w-10">
              {index + 1}
            </th>
          )
        }

        if (header.type == "action" && tableAction) {
          return <WithAction key={i} {...props} item={body} />
        }

        if (header.type == "status") {
          return (
            <td key={i} className={`${tdBodyClassName} ${header?.className ?? ""}`}>
              <div className={`capitalize badge badge-xs p-2 ${useStatus(`${header?.prefix ?? ""}${value}`)}`}>
                {useStatusLabel(`${header?.prefix ?? ""}${value}`)}
              </div>
            </td>
          )
        }

        if (header.type == "date") {
          return (
            <td key={i} className={`${tdBodyClassName} ${header?.className ?? ""}`}>
              {dateFormat(value, header.dateFormat ?? null)}
            </td>
          )
        }

        if (header.type == "currency") {
          let headerCurrencyCode = header.currency_code?.split(".")
          let currencyCode = 'IDR'
          if (headerCurrencyCode) {
            currencyCode = headerCurrencyCode.reduce((acc, key) => acc?.[key], body)
          }

          if (value == 0) {
            value = '-'
          }

          return (
            <td key={i} className={`${tdBodyClassName} ${header?.className ?? ""}`}>
              {isNumber(parseInt(Math.abs(value))) ? currency(value, "id-ID", currencyCode) : value}
            </td>
          )
        }

        if (header.type == "list") {
          const values = value.split("\n")
          let isEmpty = false
          if (values?.length == 0) {
            isEmpty = true
          }
          if (values?.length == 1 && values[0] == "") {
            isEmpty = true
          }
          if (isEmpty) return "-"

          let listClassName = header?.listClassName ?? "list-disc list-inside"

          return (
            <td key={i} className={`${tdBodyClassName} ${header?.className ?? ""}`}>
              <ul className={listClassName}>
                {values.map((value, index) => (
                  <li key={index}>{value}</li>
                ))}
              </ul>
            </td>
          )
        }

        return (
          <td key={i} className={`${tdBodyClassName} ${header?.className ?? ""}`}>
            {isModalDetail ? (
              <ModalButton id={`detail_${body?.id}`} onClick={() => setShow(body)}>
                <span>{value}</span>
              </ModalButton>
            ) : useLang(value)}
          </td>
        )
      })}
    </Fragment>
  )
}

export const WithAction = ({ tableAction, item }) => {
  return (
    <th scope="row" className="text-start w-10">
      <div className="dropdown dropdown-left">
        <div tabIndex={0} role="button" className="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">
          {tableAction && typeof tableAction === "function" && tableAction(item)}
        </ul>
      </div>
    </th>
  )
}

export const TableCard = ({ props, tableBody, tableHeader }) => {
  if (tableBody?.length == 0) {
    return (
      <div className="py-8 w-full border my-8 text-center">
        <p>Belum ada data yang dapat ditampilkan</p>
      </div>
    )
  }

  const { location, page } = usePage().props
  const { url } = useSearchParams(location)
  let isIndexView = page.url == url.pathname

  return (
    <div className={`grid grid-cols-1 sm:grid-cols-2 gap-2 my-4 justify-start w-full px-2 ${isIndexView ? 'md:grid-cols-3 2xl:grid-cols-4' : ''}`}>
      {tableBody.map((body, index) => {
        return (
          <div key={index} className={`border p-2 flex gap-2`}>
            <p>{paginationNumber(body, index)}. </p>

            <DetailModalItem data={body} tableHeader={tableHeader} />
            {isIndexView ? (
              <WithAction key={index} {...props} item={body} />
            ) : null}
          </div>
        )
      })}
    </div>
  )
}

export const tableHeightStyle = `
    [&_th]:px-2
    [&_td]:px-2 [&_td]:p-0 [&_td]:leading-tight [&_td]:min-h-0
    [&tr]:px-2 [&tr]:p-0 [&tr]:leading-tight [&tr]:min-h-0
  `

export default Table
