import { useMemo } from "react";
import {
  flexRender,
  getCoreRowModel,
  useReactTable,
  type ColumnDef,
} from "@tanstack/react-table";
import type { Expense } from "@/lib/api";
import { Button } from "@/components/ui/button";
import { CircleDollarSign, ChevronsLeftIcon, ChevronsRightIcon, SkipBackIcon, SkipForwardIcon } from "lucide-react";
import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination";

interface ExpensesTableProps {
  data: Expense[];
  onPay: (expense: Expense) => void;
  page: number;
  total: number;
  pageSize: number;
  onPageChange: (page: number) => void;
}

export function ExpensesTable({ data, onPay, page, total, pageSize, onPageChange }: ExpensesTableProps) {
  const columns = useMemo<ColumnDef<Expense>[]>(
    () => [
      {
        header: "Descripción",
        accessorKey: "description",
        cell: ({ row }) => (
          <span className="font-medium">{row.getValue("description")}</span>
        ),
      },
      {
        header: "Monto",
        accessorKey: "amount",
        cell: ({ row }) => {
          const expense = row.original;
          const isPayed = expense.status === "PAYED";
          const value = isPayed && expense.amountPayed ? Number(expense.amountPayed) : Number(expense.amount);
          return (
            <span className="tabular-nums">
              ${value.toLocaleString("es-AR", { minimumFractionDigits: 2 })}
            </span>
          );
        },
      },
      {
        header: "Vencimiento",
        accessorKey: "dueDate",
        cell: ({ row }) => {
          const dueDate = new Date(row.getValue("dueDate"));
          return (
            <span className="text-muted-foreground">
              {dueDate.toLocaleDateString("es-AR", {
                timeZone: "UTC",
                day: "2-digit",
                month: "2-digit",
                year: "numeric",
              })}
            </span>
          );
        },
      },
      {
        header: "Estado",
        accessorKey: "status",
        cell: ({ row }) => {
          const status = row.getValue("status");
          const isPayed = status === "PAYED";
          return (
            <span
              className={
                isPayed
                  ? "inline-flex h-5 items-center rounded-md bg-green-100 px-1.5 text-xs font-medium text-green-700 dark:bg-green-900/30 dark:text-green-400"
                  : "inline-flex h-5 items-center rounded-md bg-yellow-100 px-1.5 text-xs font-medium text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400"
              }
            >
              {isPayed ? "Pagado" : "Pendiente"}
            </span>
          );
        },
      },
      {
        header: "Fecha de pago",
        accessorKey: "paymentDate",
        cell: ({ row }) => {
          const paymentDate = row.getValue("paymentDate");
          if (!paymentDate) {
            return <span className="text-muted-foreground">--</span>;
          }
          const date = new Date(paymentDate as string);
          return (
            <span className="text-muted-foreground">
              {date.toLocaleDateString("es-AR", {
                timeZone: "UTC",
                day: "2-digit",
                month: "2-digit",
                year: "numeric",
              })}
            </span>
          );
        },
      },
      {
        id: "actions",
        cell: ({ row }) => {
          const expense = row.original;
          if (expense.status === "PAYED") return null;
          return (
            <div className="flex justify-end">
              <Button
                variant="outline"
                size="xs"
                onClick={() => onPay(expense)}
              >
                <CircleDollarSign className="size-3.5" />
                Pagar
              </Button>
            </div>
          );
        },
      },
    ],
    [onPay],
  );

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
  });

  const totalPages = Math.max(1, Math.ceil(total / pageSize));
  const GROUP_SIZE = 3;
  const currentGroup = Math.floor((page - 1) / GROUP_SIZE);
  const startPage = currentGroup * GROUP_SIZE + 1;
  const endPage = Math.min(startPage + GROUP_SIZE - 1, totalPages);

  return (
    <div className="space-y-4">
      <div className="overflow-x-auto rounded-lg border">
        <table className="w-full text-sm">
          <thead>
            {table.getHeaderGroups().map((headerGroup) => (
              <tr key={headerGroup.id} className="border-b bg-muted/50">
                {headerGroup.headers.map((header) => (
                  <th
                    key={header.id}
                    className="px-3 py-2 text-left text-xs font-medium text-muted-foreground"
                  >
                    {flexRender(header.column.columnDef.header, header.getContext())}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody>
            {table.getRowModel().rows.map((row) => (
              <tr key={row.id} className="border-b last:border-0 hover:bg-muted/30">
                {row.getVisibleCells().map((cell) => (
                  <td key={cell.id} className="px-3 py-2.5">
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </td>
                ))}
              </tr>
            ))}
            {table.getRowModel().rows.length === 0 && (
              <tr>
                <td colSpan={columns.length} className="px-3 py-8 text-center text-sm text-muted-foreground">
                  No hay gastos para mostrar.
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>

      {totalPages > 1 && (
        <Pagination>
          <PaginationContent>
            <PaginationItem>
              <PaginationLink
                onClick={(e) => { e.preventDefault(); onPageChange(1); }}
                href="#"
                aria-label="Ir a la primera página"
                className={page <= 1 ? "pointer-events-none opacity-50" : ""}
              >
                <SkipBackIcon className="size-4" />
              </PaginationLink>
            </PaginationItem>
            <PaginationItem>
              <PaginationPrevious
                onClick={(e) => { e.preventDefault(); if (page > 1) onPageChange(page - 1); }}
                href="#"
                className={page <= 1 ? "pointer-events-none opacity-50" : ""}
              />
            </PaginationItem>
            {currentGroup > 0 && (
              <PaginationItem>
                <PaginationLink
                  onClick={(e) => { e.preventDefault(); onPageChange(startPage - 1); }}
                  href="#"
                  aria-label="Ir al grupo anterior"
                >
                  <ChevronsLeftIcon className="size-4" />
                </PaginationLink>
              </PaginationItem>
            )}
            {Array.from({ length: endPage - startPage + 1 }, (_, i) => startPage + i).map((p) => (
              <PaginationItem key={p}>
                <PaginationLink
                  isActive={p === page}
                  onClick={(e) => { e.preventDefault(); onPageChange(p); }}
                  href="#"
                >
                  {p}
                </PaginationLink>
              </PaginationItem>
            ))}
            {(currentGroup + 1) * GROUP_SIZE < totalPages && (
              <PaginationItem>
                <PaginationLink
                  onClick={(e) => { e.preventDefault(); onPageChange(endPage + 1); }}
                  href="#"
                  aria-label="Ir al siguiente grupo"
                >
                  <ChevronsRightIcon className="size-4" />
                </PaginationLink>
              </PaginationItem>
            )}
            <PaginationItem>
              <PaginationNext
                onClick={(e) => { e.preventDefault(); if (page < totalPages) onPageChange(page + 1); }}
                href="#"
                className={page >= totalPages ? "pointer-events-none opacity-50" : ""}
              />
            </PaginationItem>
            <PaginationItem>
              <PaginationLink
                onClick={(e) => { e.preventDefault(); onPageChange(totalPages); }}
                href="#"
                aria-label="Ir a la última página"
                className={page >= totalPages ? "pointer-events-none opacity-50" : ""}
              >
                <SkipForwardIcon className="size-4" />
              </PaginationLink>
            </PaginationItem>
          </PaginationContent>
        </Pagination>
      )}
    </div>
  );
}
