'use client'

import { type ChangeEvent, type ReactNode, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { Loader2 } from 'lucide-react'
import { cn } from '@/lib/utils'

export interface Column<T> {
  key: string
  header: string
  render?: (row: T) => ReactNode
  className?: string
  sortable?: boolean
}

export interface BulkAction {
  label: string
  variant?: 'danger' | 'warning' | 'default'
  onClick: (ids: number[]) => void
}

interface PaginationMeta {
  current_page: number
  last_page: number
  per_page: number
  total: number
}

interface DataTableProps<T extends { id: number }> {
  columns: Column<T>[]
  data: T[]
  loading?: boolean
  selected?: number[]
  onSelect?: (ids: number[]) => void
  bulkActions?: BulkAction[]
  emptyMessage?: string
  pagination?: PaginationMeta
  onPageChange?: (page: number) => void
  onSearch?: (q: string) => void
  searchValue?: string
  searchPlaceholder?: string
  toolbar?: ReactNode
  sortKey?: string
  sortDir?: 'asc' | 'desc'
  onSort?: (key: string) => void
  perPage?: number
  onPerPageChange?: (n: number | 'all') => void
  onImportFile?: (text: string) => void
  onDuplicate?: (id: number) => void
}

export function DataTable<T extends { id: number }>({
  columns,
  data,
  loading,
  selected = [],
  onSelect,
  bulkActions = [],
  emptyMessage,
  pagination,
  onPageChange,
  onSearch,
  searchValue = '',
  searchPlaceholder,
  toolbar,
  sortKey,
  sortDir,
  onSort,
  perPage,
  onPerPageChange,
  onImportFile,
}: DataTableProps<T>) {
  const { t } = useTranslation()
  const fileInputRef = useRef<HTMLInputElement>(null)
  const resolvedEmptyMessage = emptyMessage ?? t('common.noResults')
  const resolvedSearchPlaceholder = searchPlaceholder ?? t('common.search')
  const allSelected = data.length > 0 && selected.length === data.length
  const someSelected = selected.length > 0 && !allSelected

  const toggleAll = () => {
    if (!onSelect) return
    onSelect(allSelected ? [] : data.map((r) => r.id))
  }

  const toggleOne = (id: number) => {
    if (!onSelect) return
    onSelect(selected.includes(id) ? selected.filter((s) => s !== id) : [...selected, id])
  }

  const handleImportChange = (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file || !onImportFile) return
    const reader = new FileReader()
    reader.onload = () => {
      onImportFile(String(reader.result ?? ''))
      if (fileInputRef.current) fileInputRef.current.value = ''
    }
    reader.readAsText(file)
  }

  const showToolbar = onSearch !== undefined || toolbar || onImportFile
  const perPageSelectValue = (() => {
    if (!pagination) return '25'
    const current = perPage ?? pagination.per_page
    return [25, 50, 100].includes(current) ? String(current) : 'all'
  })()

  return (
    <div className="flex flex-col gap-3">
      {/* Toolbar row */}
      {showToolbar && (
        <div className="flex flex-wrap items-center gap-2">
          {onSearch !== undefined && (
            <input
              type="search"
              value={searchValue}
              onChange={(e) => onSearch(e.target.value)}
              placeholder={resolvedSearchPlaceholder}
              className="h-10 flex-1 rounded-xl border border-[var(--premium-border)] bg-[var(--premium-field-bg)] px-3 text-sm text-[var(--premium-field-text)] placeholder:text-[var(--premium-field-placeholder)] focus:border-brand-400/70 focus:outline-none focus:ring-2 focus:ring-brand-400/20"
              style={{ minWidth: '180px', maxWidth: '320px' }}
            />
          )}
          <div className="ml-auto flex items-center gap-2">
            {onImportFile && (
              <>
                <input
                  ref={fileInputRef}
                  type="file"
                  accept=".csv,.txt,.json"
                  className="hidden"
                  onChange={handleImportChange}
                />
                <button
                  type="button"
                  onClick={() => fileInputRef.current?.click()}
                  className="press-btn rounded-lg border border-[var(--premium-border)] px-3 py-1.5 text-xs font-semibold text-[var(--premium-muted-text)] hover:bg-[var(--premium-hover-bg)]"
                >
                  Import
                </button>
              </>
            )}
            {toolbar}
          </div>
        </div>
      )}

      {/* Bulk actions bar */}
      {selected.length > 0 && bulkActions.length > 0 && (
        <div className="premium-card animate-fade-in-up flex items-center gap-3 rounded-2xl px-4 py-2.5 text-sm">
          <span className="font-medium text-[var(--premium-label)]">{t('common.selected', { count: selected.length })}</span>
          <div className="h-4 w-px bg-[var(--premium-divider)]" />
          {bulkActions.map((action) => (
            <button
              key={action.label}
              type="button"
              onClick={() => action.onClick(selected)}
              className={cn(
                'press-btn rounded-lg px-3 py-1 text-xs font-semibold text-white transition-colors',
                action.variant === 'danger'
                  ? 'bg-red-600/80 hover:bg-red-600'
                  : action.variant === 'warning'
                  ? 'bg-amber-600/80 hover:bg-amber-600'
                  : 'bg-brand-600/80 hover:bg-brand-600',
              )}
            >
              {action.label}
            </button>
          ))}
          <button
            type="button"
            onClick={() => onSelect?.([])}
            className="ml-auto text-xs text-[var(--premium-muted-text)] hover:text-[var(--premium-text)]"
          >
            {t('common.clear')}
          </button>
        </div>
      )}

      {/* Table */}
      <div className="premium-card premium-card-glow overflow-x-auto rounded-2xl">
        <table className="w-full min-w-[580px] text-left text-sm">
          <thead className="bg-[var(--premium-header-bg)] text-[var(--premium-muted-text)] shadow-[inset_0_-1px_0_var(--premium-divider)]">
            <tr>
              {onSelect && (
                <th className="w-10 px-4 py-3">
                  <input
                    type="checkbox"
                    checked={allSelected}
                    ref={(el) => { if (el) el.indeterminate = someSelected }}
                    onChange={toggleAll}
                    className="h-4 w-4 cursor-pointer accent-brand-500"
                  />
                </th>
              )}
              {columns.map((col) => {
                const canSort = Boolean(col.sortable && onSort)
                const isActive = sortKey === col.key
                return (
                  <th key={col.key} className={cn('px-4 py-3 font-medium', col.className)}>
                    {canSort ? (
                      <button
                        type="button"
                        onClick={() => onSort?.(col.key)}
                        className="inline-flex items-center gap-1 hover:text-[var(--premium-text)]"
                      >
                        {col.header}
                        <span className="text-[10px] opacity-70" aria-hidden>
                          {isActive ? (sortDir === 'desc' ? '↓' : '↑') : '↑↓'}
                        </span>
                      </button>
                    ) : (
                      col.header
                    )}
                  </th>
                )
              })}
            </tr>
          </thead>
          <tbody>
            {loading ? (
              <tr>
                <td
                  colSpan={columns.length + (onSelect ? 1 : 0)}
                  className="px-4 py-12 text-center text-[var(--premium-muted-text)]"
                >
                  <Loader2 size={22} className="mx-auto animate-spin text-brand-500" />
                </td>
              </tr>
            ) : data.length === 0 ? (
              <tr>
                <td
                  colSpan={columns.length + (onSelect ? 1 : 0)}
                  className="px-4 py-10 text-center text-[var(--premium-muted-text)]"
                >
                  {resolvedEmptyMessage}
                </td>
              </tr>
            ) : (
              data.map((row) => {
                const isSelected = selected.includes(row.id)
                return (
                  <tr
                    key={row.id}
                    className={cn(
                      'border-t border-[var(--premium-divider)] transition-all',
                      isSelected
                        ? 'bg-brand-500/12 shadow-[inset_3px_0_0_rgba(233,180,76,0.75)]'
                        : 'hover:bg-[var(--premium-hover-bg)] hover:shadow-[inset_3px_0_0_rgba(61,139,110,0.45)]',
                    )}
                  >
                    {onSelect && (
                      <td className="px-4 py-3">
                        <input
                          type="checkbox"
                          checked={isSelected}
                          onChange={() => toggleOne(row.id)}
                          className="h-4 w-4 cursor-pointer accent-brand-500"
                        />
                      </td>
                    )}
                    {columns.map((col) => (
                      <td key={col.key} className={cn('px-4 py-3 text-[var(--premium-text)]', col.className)}>
                        {col.render ? col.render(row) : (row as Record<string, unknown>)[col.key] as ReactNode}
                      </td>
                    ))}
                  </tr>
                )
              })
            )}
          </tbody>
        </table>
      </div>

      {/* Pagination */}
      {pagination && (
        <div className="flex flex-wrap items-center justify-between gap-2 text-sm text-[var(--premium-muted-text)]">
          <span>
            {t('common.pageOf', {
              current: pagination.current_page,
              last: pagination.last_page,
              total: pagination.total,
            })}
          </span>
          <div className="flex flex-wrap items-center gap-2">
            {onPerPageChange && (
              <label className="flex items-center gap-1.5 text-xs">
                <span>Per page</span>
                <select
                  value={perPageSelectValue}
                  onChange={(e) => {
                    const v = e.target.value
                    onPerPageChange(v === 'all' ? 'all' : Number(v))
                  }}
                  className="rounded-lg border border-[var(--premium-border)] bg-[var(--premium-field-bg)] px-2 py-1.5 text-xs text-[var(--premium-field-text)]"
                >
                  <option value="25">25</option>
                  <option value="50">50</option>
                  <option value="100">100</option>
                  <option value="all">All</option>
                </select>
              </label>
            )}
            {pagination.last_page > 1 && (
              <div className="flex gap-1">
                <button
                  type="button"
                  onClick={() => onPageChange?.(pagination.current_page - 1)}
                  disabled={pagination.current_page <= 1}
                  className="press-btn rounded-lg border border-[var(--premium-border)] px-3 py-1.5 text-xs text-[var(--premium-muted-text)] disabled:opacity-40 hover:bg-[var(--premium-hover-bg)]"
                >
                  {t('common.previous')}
                </button>
                {Array.from({ length: Math.min(5, pagination.last_page) }, (_, i) => {
                  const start = Math.max(1, pagination.current_page - 2)
                  const page = start + i
                  if (page > pagination.last_page) return null
                  return (
                    <button
                      key={page}
                      type="button"
                      onClick={() => onPageChange?.(page)}
                      className={cn(
                        'press-btn rounded-lg border px-3 py-1.5 text-xs',
                        page === pagination.current_page
                          ? 'border-brand-400 bg-brand-500 text-white'
                          : 'border-[var(--premium-border)] text-[var(--premium-muted-text)] hover:bg-[var(--premium-hover-bg)]',
                      )}
                    >
                      {page}
                    </button>
                  )
                })}
                <button
                  type="button"
                  onClick={() => onPageChange?.(pagination.current_page + 1)}
                  disabled={pagination.current_page >= pagination.last_page}
                  className="press-btn rounded-lg border border-[var(--premium-border)] px-3 py-1.5 text-xs text-[var(--premium-muted-text)] disabled:opacity-40 hover:bg-[var(--premium-hover-bg)]"
                >
                  {t('common.next')}
                </button>
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  )
}
