"use client"

import * as React from "react"
import {
  flexRender,
  getCoreRowModel,
  useReactTable,
} from "@tanstack/react-table"
import { useRouter } from "next/navigation"

import { useDebouncedValue } from "@/app/dashboard/_components/data-table"
import { Input } from "@/components/ui/input"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
import { SETTINGS_INPUT_CLASS } from "@/components/settings/constants"
import { cn } from "@/lib/utils"
import {
  XmlApiPaginatedRange,
  XmlApiServerPagination,
} from "@/components/xml-apis/shared/xml-api-server-pagination"

import { createCurrencyConversionColumns } from "./columns"
import { listHref, type CurrencyConversionTab } from "./constants"
import type { CurrencyConversionRow } from "./schema"

type FilterState = {
  srNo: string
  isin: string
  name: string
  fromCurrency: string
  toCurrency: string
  conversionRate: string
  conversionRateCurrency: string
  dataUpdateDate: string
  conversionRateDate2: string
}

type Props = {
  data: CurrencyConversionRow[]
  filters: FilterState
  activeTab: CurrencyConversionTab
  totalCount: number
  page: number
  pageSize: number
  pageCount: number
}

const filterInputClass = cn(SETTINGS_INPUT_CLASS, "h-8")

const FILTER_COLS = [
  "srNo",
  "isin",
  "name",
  "fromCurrency",
  "toCurrency",
  "conversionRate",
  "conversionRateCurrency",
  "dataUpdateDate",
  "conversionRateDate2",
] as const

type FilterCol = (typeof FILTER_COLS)[number]

export function CurrencyConversionTable({
  data,
  filters,
  activeTab,
  totalCount,
  page,
  pageSize,
  pageCount,
}: Props) {
  const router = useRouter()
  const [drafts, setDrafts] = React.useState<FilterState>(filters)
  const debouncedSrNo = useDebouncedValue(drafts.srNo)
  const debouncedIsin = useDebouncedValue(drafts.isin)
  const debouncedName = useDebouncedValue(drafts.name)
  const debouncedFromCurrency = useDebouncedValue(drafts.fromCurrency)
  const debouncedToCurrency = useDebouncedValue(drafts.toCurrency)
  const debouncedConversionRate = useDebouncedValue(drafts.conversionRate)
  const debouncedConversionRateCurrency = useDebouncedValue(drafts.conversionRateCurrency)
  const debouncedDataUpdateDate = useDebouncedValue(drafts.dataUpdateDate)
  const debouncedConversionRateDate2 = useDebouncedValue(drafts.conversionRateDate2)

  const navigate = React.useCallback(
    (
      next: Partial<FilterState> & { tab?: CurrencyConversionTab; page?: number; pageSize?: number },
      options?: { replace?: boolean },
    ) => {
      const href = listHref({
        tab: next.tab ?? activeTab,
        srNo: next.srNo ?? filters.srNo,
        isin: next.isin ?? filters.isin,
        name: next.name ?? filters.name,
        fromCurrency: next.fromCurrency ?? filters.fromCurrency,
        toCurrency: next.toCurrency ?? filters.toCurrency,
        conversionRate: next.conversionRate ?? filters.conversionRate,
        conversionRateCurrency:
          next.conversionRateCurrency ?? filters.conversionRateCurrency,
        dataUpdateDate: next.dataUpdateDate ?? filters.dataUpdateDate,
        conversionRateDate2: next.conversionRateDate2 ?? filters.conversionRateDate2,
        page: next.page ?? page,
        pageSize: next.pageSize ?? pageSize,
      })

      if (options?.replace) {
        router.replace(href, { scroll: false })
        return
      }

      router.push(href, { scroll: false })
    },
    [activeTab, filters, page, pageSize, router],
  )

  React.useEffect(() => {
    setDrafts(filters)
  }, [filters])

  React.useEffect(() => {
    const next: FilterState = {
      srNo: debouncedSrNo.trim(),
      isin: debouncedIsin.trim(),
      name: debouncedName.trim(),
      fromCurrency: debouncedFromCurrency.trim(),
      toCurrency: debouncedToCurrency.trim(),
      conversionRate: debouncedConversionRate.trim(),
      conversionRateCurrency: debouncedConversionRateCurrency.trim(),
      dataUpdateDate: debouncedDataUpdateDate.trim(),
      conversionRateDate2: debouncedConversionRateDate2.trim(),
    }

    const changed = FILTER_COLS.some((key) => next[key] !== filters[key])
    if (!changed) return
    navigate({ ...next, page: 1 }, { replace: true })
  }, [
    debouncedSrNo,
    debouncedIsin,
    debouncedName,
    debouncedFromCurrency,
    debouncedToCurrency,
    debouncedConversionRate,
    debouncedConversionRateCurrency,
    debouncedDataUpdateDate,
    debouncedConversionRateDate2,
    filters,
    navigate,
  ])

  const columns = React.useMemo(() => createCurrencyConversionColumns(), [])

  const table = useReactTable({
    data,
    columns,
    getRowId: (r) => r.srNo,
    getCoreRowModel: getCoreRowModel(),
  })

  const headers = table.getHeaderGroups()[0]?.headers ?? []

  return (
    <div className="space-y-4">
      <XmlApiPaginatedRange page={page} pageSize={pageSize} totalCount={totalCount} />
      <div className="overflow-x-auto rounded-lg border bg-card">
        <Table>
          <TableHeader>
            <TableRow className="bg-muted/40 hover:bg-muted/40">
              {headers.map((h) => (
                <TableHead key={h.id} className="h-10 px-3 whitespace-nowrap">
                  {flexRender(h.column.columnDef.header, h.getContext())}
                </TableHead>
              ))}
            </TableRow>
            <TableRow className="bg-muted/20 hover:bg-muted/20">
              {headers.map((h) => {
                const colId = h.column.id as FilterCol
                const hasFilter = FILTER_COLS.includes(colId)
                return (
                  <TableHead key={h.id} className="px-3 py-2">
                    {hasFilter ? (
                      <Input
                        className={filterInputClass}
                        placeholder="Filter"
                        value={drafts[colId]}
                        onChange={(e) =>
                          setDrafts((prev) => ({ ...prev, [colId]: e.target.value }))
                        }
                      />
                    ) : null}
                  </TableHead>
                )
              })}
            </TableRow>
          </TableHeader>
          <TableBody>
            {table.getRowModel().rows.length ? (
              table.getRowModel().rows.map((row) => (
                <TableRow key={row.id}>
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id} className="px-3 py-2.5">
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell
                  colSpan={columns.length}
                  className="h-24 text-center text-muted-foreground"
                >
                  No records found.
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>
      <XmlApiServerPagination
        page={page}
        pageSize={pageSize}
        pageCount={pageCount}
        totalCount={totalCount}
        onPageChange={(nextPage) => navigate({ page: nextPage })}
        onPageSizeChange={(nextPageSize) => navigate({ page: 1, pageSize: nextPageSize })}
        pageSizeOptions={[20, 50, 100]}
      />
    </div>
  )
}
