'use client'

import type { WebhookDeliveryEntry } from '@admin/actions/webhooks'
import type { ColumnDef } from '@tanstack/react-table'
import {
  DataGrid,
  DataGridBody,
  DataGridCell,
  DataGridHead,
  DataGridHeader,
  DataGridRow
} from '@admin/components/shared/data-table/data-grid'
import { DataTablePagination } from '@admin/components/shared/data-table/data-table-pagination'
import { useTableUtils } from '@admin/hooks/use-table-utils'
import { useWebhookDeliveries } from '@admin/hooks/use-webhooks'
import { cn } from '@admin/utils/shared/cn'
import { flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'
import { GripVertical } from 'lucide-react'
import { parseAsInteger, parseAsString, useQueryStates } from 'nuqs'

interface WebhooksLogsTableProps<TValue> extends React.HTMLAttributes<HTMLDivElement> {
  columns: ColumnDef<WebhookDeliveryEntry, TValue>[]
  search?: string
  status?: string
  endpoint?: string
  createdAtFrom?: string
  createdAtTo?: string
}

export function WebhooksLogsTable<TValue>({
  columns,
  search,
  status,
  endpoint,
  createdAtFrom,
  createdAtTo,
  className
}: WebhooksLogsTableProps<TValue>) {
  const defaultPageSize = 20
  const [{ page: pageIndex, size: pageSize, sort: sortField, dir: sortDir }, setTableQuery] =
    useQueryStates({
      page: parseAsInteger.withDefault(0),
      size: parseAsInteger.withDefault(defaultPageSize),
      sort: parseAsString.withDefault(''),
      dir: parseAsString.withDefault('')
    })

  const safePageIndex = Number.isFinite(pageIndex) && pageIndex > 0 ? pageIndex : 0
  const safePageSize =
    pageSize === -1 || (Number.isFinite(pageSize) && pageSize > 0) ? pageSize : defaultPageSize
  const { data, error, isPending } = useWebhookDeliveries(
    search,
    status,
    endpoint,
    createdAtFrom,
    createdAtTo,
    safePageIndex,
    safePageSize,
    sortField || undefined,
    (sortDir as 'asc' | 'desc') || undefined
  )

  const tableData = data?.deliveries ?? []
  const totalRows = data?.total ?? 0
  const effectivePageSize = safePageSize === -1 ? totalRows : safePageSize
  const pageCount = effectivePageSize > 0 ? Math.ceil(totalRows / effectivePageSize) : 1
  const shouldShowPagination = totalRows > defaultPageSize

  const {
    columnSizing,
    handleColumnSizingChange,
    handlePaginationChange,
    handleSortingChange,
    hoveredColumnId,
    registerTable,
    resetColumnSizingToContainer,
    setHoveredColumnId,
    sorting,
    tableContainerRef
  } = useTableUtils<WebhookDeliveryEntry>({
    data: tableData,
    pageIndex: safePageIndex,
    pageSize: effectivePageSize,
    setPageIndex: (nextPageIndex) => setTableQuery({ page: nextPageIndex }),
    setSortingParams: ({
      pageIndex: nextPageIndex,
      sortDir: nextSortDir,
      sortField: nextSortField
    }) =>
      setTableQuery({
        page: nextPageIndex,
        sort: nextSortField,
        dir: nextSortDir
      }),
    sortField,
    sortDir
  })

  const table = useReactTable({
    data: tableData,
    columns,
    columnResizeMode: 'onChange',
    defaultColumn: {
      minSize: 48,
      size: 220
    },
    getCoreRowModel: getCoreRowModel(),
    manualPagination: true,
    manualSorting: true,
    pageCount,
    rowCount: totalRows,
    onSortingChange: handleSortingChange,
    onColumnSizingChange: handleColumnSizingChange,
    onPaginationChange: handlePaginationChange,
    state: {
      sorting,
      columnSizing,
      pagination: {
        pageIndex: safePageIndex,
        pageSize: effectivePageSize
      }
    }
  })
  registerTable(table)
  const gridTemplateColumns = table
    .getVisibleLeafColumns()
    .map((column) => `${column.getSize()}px`)
    .join(' ')

  return (
    <div className={cn('flex h-full flex-col gap-6 pt-px pb-2', className)}>
      <DataGrid
        containerClassName="min-h-0 flex-1"
        containerRef={tableContainerRef}
        gridTemplateColumns={gridTemplateColumns}
        style={{ width: table.getTotalSize() }}
      >
        <DataGridHeader>
          {table.getHeaderGroups().map((headerGroup) => (
            <DataGridRow key={headerGroup.id}>
              {headerGroup.headers.map((header, headerIndex) => {
                const resizeLabel =
                  typeof header.column.columnDef.header === 'string'
                    ? header.column.columnDef.header
                    : header.column.id
                const nextHeader = headerGroup.headers[headerIndex + 1]
                const canResizeColumn =
                  header.column.getCanResize() && nextHeader?.column.getCanResize() === true
                return (
                  <DataGridHead
                    key={header.id}
                    className="group/resize-header relative overflow-hidden"
                    data-column-id={header.column.id}
                    onMouseEnter={() => setHoveredColumnId(header.column.id)}
                    onMouseLeave={() =>
                      setHoveredColumnId((current) =>
                        current === header.column.id ? null : current
                      )
                    }
                  >
                    {header.isPlaceholder
                      ? null
                      : flexRender(header.column.columnDef.header, header.getContext())}
                    {canResizeColumn ? (
                      <button
                        type="button"
                        aria-label={`Resize ${resizeLabel} column`}
                        className="group/resize-handle absolute top-0 right-0 z-10 flex h-full w-5 cursor-col-resize touch-none items-center justify-center text-muted-foreground opacity-0 transition-opacity select-none group-focus-within/resize-header:opacity-100 hover:text-foreground focus-visible:text-foreground focus-visible:opacity-100 focus-visible:outline-none data-[column-hovered=true]:opacity-100 data-[resizing=true]:opacity-100"
                        data-resize-handle
                        data-column-hovered={
                          hoveredColumnId === header.column.id ? 'true' : 'false'
                        }
                        data-resizing={header.column.getIsResizing() ? 'true' : 'false'}
                        onDoubleClick={resetColumnSizingToContainer}
                        onMouseDown={header.getResizeHandler()}
                        onTouchStart={header.getResizeHandler()}
                      >
                        <GripVertical
                          aria-hidden="true"
                          className={cn('size-3.5', {
                            'text-ring': header.column.getIsResizing()
                          })}
                        />
                      </button>
                    ) : null}
                  </DataGridHead>
                )
              })}
            </DataGridRow>
          ))}
        </DataGridHeader>
        <DataGridBody>
          {isPending ? (
            <DataGridRow>
              <DataGridCell
                className="flex h-24 items-center justify-center text-center"
                style={{ gridColumn: '1 / -1' }}
              >
                <div className="text-muted-foreground">Loading deliveries…</div>
              </DataGridCell>
            </DataGridRow>
          ) : error ? (
            <DataGridRow>
              <DataGridCell
                className="flex h-24 items-center justify-center text-center"
                style={{ gridColumn: '1 / -1' }}
              >
                <div className="text-destructive">
                  Failed to load deliveries. Refresh to try again.
                </div>
              </DataGridCell>
            </DataGridRow>
          ) : table.getRowModel().rows?.length ? (
            table.getRowModel().rows.map((row) => (
              <DataGridRow key={row.id} className="hover:bg-muted/50">
                {row.getVisibleCells().map((cell) => (
                  <DataGridCell
                    key={cell.id}
                    data-column-id={cell.column.id}
                    onMouseEnter={() => setHoveredColumnId(cell.column.id)}
                    onMouseLeave={() =>
                      setHoveredColumnId((current) => (current === cell.column.id ? null : current))
                    }
                  >
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </DataGridCell>
                ))}
              </DataGridRow>
            ))
          ) : (
            <DataGridRow>
              <DataGridCell
                className="flex h-24 items-center justify-center text-center"
                style={{ gridColumn: '1 / -1' }}
              >
                No deliveries found.
              </DataGridCell>
            </DataGridRow>
          )}
        </DataGridBody>
      </DataGrid>

      {shouldShowPagination ? (
        <DataTablePagination
          table={table}
          paginationMode="controlled"
          pageSize={safePageSize}
          pageIndex={safePageIndex}
          pageCount={pageCount}
          setPageIndex={(nextPageIndex) => setTableQuery({ page: nextPageIndex })}
          setPageSize={(nextPageSize) => setTableQuery({ page: 0, size: nextPageSize })}
        />
      ) : null}
    </div>
  )
}
