import { format } from 'date-fns';
import { ChangeEvent, useEffect, useState } from 'react';

import TableLoadingOverlay from '@/shared/components/table-loading-overlay';
import { useTextController } from '@/shared/language/hooks/use-text-controller';
import {
  Table,
  TableBody,
  TableCell,
  TableHeader,
  TableRow,
} from '@/shared/shadcn-ui/table';

import { TransactionsTablePagination } from './table-pagination';
import { TransactionsTableHeader } from './transactions-table-header';

export interface TransactionRequest {
  start_date?: string;
  end_date?: string;
  page: number;
  limit: number;
}

export interface TransactionsTableProps<T> {
  data: {
    transactions: T[];
    total_pages: number;
    total_records: number;
  };
  isLoading: boolean;
  onChange: (request: TransactionRequest) => void;
  renderHeaders: () => React.ReactNode;
  renderRow: (transaction: T, index: number) => React.ReactNode;
  itemsPerPageOptions?: number[];
}

export const TransactionsTable = <T,>({
  data,
  isLoading,
  onChange,
  renderHeaders,
  renderRow,
  itemsPerPageOptions = [5, 10, 20, 50],
}: TransactionsTableProps<T>) => {
  const [startDate, setStartDate] = useState<Date | undefined>(
    new Date(new Date().setMonth(new Date().getMonth() - 1)),
  );
  const [endDate, setEndDate] = useState<Date | undefined>(new Date());
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(itemsPerPageOptions[0]);

  const handlePageChange = (page: number) => {
    if (page < 1 || page > data.total_pages) return;
    setCurrentPage(page);
  };

  const handleItemsPerPageChange = (e: ChangeEvent<HTMLSelectElement>) => {
    setItemsPerPage(Number(e.target.value));
    setCurrentPage(1); // Reset to first page when changing items per page
  };

  const filterTransactions = () => {
    if (!startDate || !endDate) return;
    setCurrentPage(1); // Reset to the first page when applying filters
  };

  const { t } = useTextController();

  useEffect(() => {
    onChange({
      limit: itemsPerPage,
      page: currentPage,
      ...(startDate ? { start_date: format(startDate, 'yyyy-MM-dd') } : {}),
      ...(endDate ? { end_date: format(endDate, 'yyyy-MM-dd') } : {}),
    });
  }, [startDate, endDate, itemsPerPage, currentPage]);

  if (!data) return null;

  return (
    <div className='relative space-y-6'>
      <TableLoadingOverlay isLoading={isLoading} />
      <TransactionsTableHeader
        startDate={startDate}
        setStartDate={setStartDate}
        endDate={endDate}
        setEndDate={setEndDate}
      />

      <div className='relative rounded-md border'>
        <Table>
          <TableHeader>{renderHeaders()}</TableHeader>
          <TableBody>
            {data.transactions.length > 0 ? (
              data.transactions.map((transaction, index) =>
                renderRow(transaction, index),
              )
            ) : (
              <TableRow>
                <TableCell
                  colSpan={6}
                  className='py-6 text-center text-gray-500'
                >
                  {t('corporate.transactions.no-data')}
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>
      <TransactionsTablePagination
        currentPage={currentPage}
        itemsPerPage={itemsPerPage}
        itemsPerPageOptions={itemsPerPageOptions}
        totalPages={data.total_pages}
        transactionsQuantity={data.transactions.length}
        totalOperations={data.total_records}
        onPageChange={handlePageChange}
        onItemsPerPageChange={handleItemsPerPageChange}
      />
    </div>
  );
};
