"use client";

import React, { useState } from "react";
import { ColumnDef, flexRender, getCoreRowModel, useReactTable, getPaginationRowModel, getSortedRowModel, SortingState, getFilteredRowModel, ColumnFiltersState, Column } from "@tanstack/react-table";
import { Input } from "@/shared/components/ui/input";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/shared/components/ui/table";
import { Button } from "@/shared/components/ui/button";
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, ChevronsUpDown } from "lucide-react";

interface DataTableProps<TData, TValue> {
  columns: ColumnDef<TData, TValue>[];
  data: TData[];
  searchColumn?: string;
  searchPlaceholder?: string;
  pageSize?: number;
}

export function createSortableHeader<T>(label: string) {
  const SortableHeader = ({ column }: { column: Column<T, unknown> }) => {
    return (
      <Button variant="ghost" onClick={() => column.toggleSorting(column.getIsSorted() === "asc")} className="flex items-center gap-1 font-medium">
        {label}
        <ChevronsUpDown className="ml-2 h-4 w-4" />
      </Button>
    );
  };

  SortableHeader.displayName = `SortableHeader(${label})`;

  return SortableHeader;
}

export function DataTable<TData, TValue>({ columns, data, searchColumn, searchPlaceholder = "Search...", pageSize = 10 }: Readonly<DataTableProps<TData, TValue>>) {
  const [sorting, setSorting] = useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
  const [searchValue, setSearchValue] = useState("");

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    state: {
      sorting,
      columnFilters,
    },
    initialState: {
      pagination: {
        pageSize,
      },
    },
  });

  const handleSearch = (value: string) => {
    setSearchValue(value);
    if (searchColumn) {
      table.getColumn(searchColumn)?.setFilterValue(value);
    }
  };

  const renderPageNumbers = () => {
    const currentPage = table.getState().pagination.pageIndex + 1;
    const pageCount = table.getPageCount();
    const pagesToShow = 5;
    const halfPagesToShow = Math.floor(pagesToShow / 2);

    let startPage = Math.max(1, currentPage - halfPagesToShow);
    let endPage = Math.min(pageCount, currentPage + halfPagesToShow);

    if (currentPage <= halfPagesToShow) {
      endPage = Math.min(pagesToShow, pageCount);
    }

    if (currentPage >= pageCount - halfPagesToShow) {
      startPage = Math.max(1, pageCount - pagesToShow + 1);
    }

    const pages = [];
    for (let i = startPage; i <= endPage; i++) {
      pages.push(
        <Button key={i} variant={i === currentPage ? "default" : "outline"} size="sm" onClick={() => table.setPageIndex(i - 1)}>
          {i}
        </Button>
      );
    }

    return (
      <div className="flex items-center space-x-1">
        {currentPage > halfPagesToShow + 1 && pageCount > pagesToShow && (
          <>
            <Button variant="outline" size="sm" onClick={() => table.setPageIndex(0)}>
              <ChevronsLeft className="h-4 w-4" />
            </Button>
            <span className="px-2">...</span>
          </>
        )}
        {pages}
        {currentPage < pageCount - halfPagesToShow && pageCount > pagesToShow && (
          <>
            <span className="px-2">...</span>
            <Button variant="outline" size="sm" onClick={() => table.setPageIndex(pageCount - 1)}>
              <ChevronsRight className="h-4 w-4" />
            </Button>
          </>
        )}
      </div>
    );
  };

  return (
    <div className="space-y-4">
      {/* Search Input */}
      {searchColumn && (
        <div className="flex items-center w-full max-w-sm">
          <Input placeholder={searchPlaceholder} value={searchValue} onChange={(e) => handleSearch(e.target.value)} className="max-w-sm" />
        </div>
      )}

      {/* Table */}
      <Table>
        <TableHeader>
          {table.getHeaderGroups().map((headerGroup) => (
            <TableRow key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <TableHead key={header.id} className="text-zinc-500 font-normal">
                  {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
                </TableHead>
              ))}
            </TableRow>
          ))}
        </TableHeader>
        <TableBody>
          {table.getRowModel().rows?.length ? (
            table.getRowModel().rows.map((row) => (
              <TableRow key={row.id} data-state={row.getIsSelected() && "selected"}>
                {row.getVisibleCells().map((cell) => (
                  <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
                ))}
              </TableRow>
            ))
          ) : (
            <TableRow>
              <TableCell colSpan={columns.length} className="h-24 text-center">
                No results.
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </Table>

      {/* Pagination */}
      <div className="flex items-center justify-between">
        <div className="text-sm text-gray-500">
          Showing <strong>{table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1}</strong> to{" "}
          <strong>{Math.min((table.getState().pagination.pageIndex + 1) * table.getState().pagination.pageSize, table.getFilteredRowModel().rows.length)}</strong> of <strong>{table.getFilteredRowModel().rows.length}</strong> results
        </div>
        <div className="flex items-center space-x-2">
          <Button variant="outline" size="sm" onClick={() => table.previousPage()} disabled={!table.getCanPreviousPage()}>
            <ChevronLeft className="h-4 w-4" />
          </Button>

          {renderPageNumbers()}

          <Button variant="outline" size="sm" onClick={() => table.nextPage()} disabled={!table.getCanNextPage()}>
            <ChevronRight className="h-4 w-4" />
          </Button>
        </div>
      </div>
    </div>
  );
}
