/**
 * Advanced Bookings Table with TanStack Table and Virtual Scrolling
 */

'use client';

import React, { useMemo, useRef } from 'react';
import {
  useReactTable,
  getCoreRowModel,
  getSortedRowModel,
  flexRender,
  ColumnDef,
  SortingState,
} from '@tanstack/react-table';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useTranslations, useLocale } from 'next-intl';
import { Booking, BookingStatus } from '@/types/booking';
import { format } from 'date-fns';
import { fr, enUS } from 'date-fns/locale';

interface BookingsTableProps {
  bookings: Booking[];
  selectedBookings: Set<string>;
  onToggleSelection: (bookingId: string) => void;
  onToggleAll: () => void;
  onRowClick?: (booking: Booking) => void;
}

export const BookingsTable: React.FC<BookingsTableProps> = ({
  bookings,
  selectedBookings,
  onToggleSelection,
  onToggleAll,
  onRowClick,
}) => {
  const t = useTranslations('components.bookingsTable');
  const locale = useLocale();
  const dateFnsLocale = locale === 'fr' ? fr : enUS;
  const dateFormat = locale === 'fr' ? 'dd MMM yyyy' : 'MMM dd, yyyy';
  const tableContainerRef = useRef<HTMLDivElement>(null);
  const [sorting, setSorting] = React.useState<SortingState>([]);

  const columns = useMemo<ColumnDef<Booking>[]>(
    () => [
      {
        id: 'select',
        header: () => (
          <input
            type="checkbox"
            checked={selectedBookings.size === bookings.length && bookings.length > 0}
            onChange={onToggleAll}
            className="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
          />
        ),
        cell: ({ row }) => (
          <input
            type="checkbox"
            checked={selectedBookings.has(row.original.id)}
            onChange={() => onToggleSelection(row.original.id)}
            onClick={e => e.stopPropagation()}
            className="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
          />
        ),
        size: 50,
      },
      {
        accessorKey: 'bookingNumber',
        header: t('headers.bookingNumber'),
        cell: info => (
          <span className="font-medium text-blue-600">{info.getValue() as string}</span>
        ),
        size: 150,
      },
      {
        accessorKey: 'status',
        header: t('headers.status'),
        cell: info => {
          const status = info.getValue() as BookingStatus;
          return (
            <span
              className={`px-2 py-1 rounded-full text-xs font-medium ${getStatusColor(status)}`}
            >
              {status.replace('_', ' ').toUpperCase()}
            </span>
          );
        },
        size: 120,
      },
      {
        accessorKey: 'rateQuote.carrierName',
        header: t('headers.carrier'),
        cell: info => info.getValue() as string,
        size: 150,
      },
      {
        accessorKey: 'rateQuote.origin',
        header: t('headers.origin'),
        cell: info => info.getValue() as string,
        size: 120,
      },
      {
        accessorKey: 'rateQuote.destination',
        header: t('headers.destination'),
        cell: info => info.getValue() as string,
        size: 120,
      },
      {
        accessorKey: 'shipper.name',
        header: t('headers.shipper'),
        cell: info => info.getValue() as string,
        size: 150,
      },
      {
        accessorKey: 'consignee.name',
        header: t('headers.consignee'),
        cell: info => info.getValue() as string,
        size: 150,
      },
      {
        accessorKey: 'rateQuote.etd',
        header: t('headers.etd'),
        cell: info => {
          const value = info.getValue();
          return value
            ? format(new Date(value as string), dateFormat, { locale: dateFnsLocale })
            : '-';
        },
        size: 120,
      },
      {
        accessorKey: 'rateQuote.eta',
        header: t('headers.eta'),
        cell: info => {
          const value = info.getValue();
          return value
            ? format(new Date(value as string), dateFormat, { locale: dateFnsLocale })
            : '-';
        },
        size: 120,
      },
      {
        accessorKey: 'containers',
        header: t('headers.containers'),
        cell: info => {
          const containers = info.getValue() as any[];
          return <span>{containers.length}</span>;
        },
        size: 100,
      },
      {
        accessorKey: 'createdAt',
        header: t('headers.created'),
        cell: info =>
          format(new Date(info.getValue() as string), dateFormat, { locale: dateFnsLocale }),
        size: 120,
      },
    ],
    [
      bookings.length,
      selectedBookings,
      onToggleAll,
      onToggleSelection,
      t,
      dateFnsLocale,
      dateFormat,
    ]
  );

  const table = useReactTable({
    data: bookings,
    columns,
    state: {
      sorting,
    },
    onSortingChange: setSorting,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
  });

  const { rows } = table.getRowModel();

  const rowVirtualizer = useVirtualizer({
    count: rows.length,
    getScrollElement: () => tableContainerRef.current,
    estimateSize: () => 60,
    overscan: 10,
  });

  const virtualRows = rowVirtualizer.getVirtualItems();
  const totalSize = rowVirtualizer.getTotalSize();

  const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start || 0 : 0;
  const paddingBottom =
    virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end || 0) : 0;

  return (
    <div className="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
      <div ref={tableContainerRef} className="overflow-auto" style={{ height: '600px' }}>
        <table className="min-w-full divide-y divide-gray-200">
          <thead className="bg-gray-50 sticky top-0 z-10">
            {table.getHeaderGroups().map(headerGroup => (
              <tr key={headerGroup.id}>
                {headerGroup.headers.map(header => (
                  <th
                    key={header.id}
                    className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100"
                    style={{ width: header.getSize() }}
                    onClick={header.column.getToggleSortingHandler()}
                  >
                    <div className="flex items-center gap-2">
                      {flexRender(header.column.columnDef.header, header.getContext())}
                      {header.column.getIsSorted() && (
                        <span>{header.column.getIsSorted() === 'asc' ? '↑' : '↓'}</span>
                      )}
                    </div>
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody className="bg-white divide-y divide-gray-200">
            {paddingTop > 0 && (
              <tr>
                <td style={{ height: `${paddingTop}px` }} />
              </tr>
            )}
            {virtualRows.map(virtualRow => {
              const row = rows[virtualRow.index];
              return (
                <tr
                  key={row.id}
                  onClick={() => onRowClick?.(row.original)}
                  className={`hover:bg-gray-50 cursor-pointer ${
                    selectedBookings.has(row.original.id) ? 'bg-blue-50' : ''
                  }`}
                  style={{ height: `${virtualRow.size}px` }}
                >
                  {row.getVisibleCells().map(cell => (
                    <td
                      key={cell.id}
                      className="px-6 py-4 whitespace-nowrap text-sm text-gray-900"
                      style={{ width: cell.column.getSize() }}
                    >
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </td>
                  ))}
                </tr>
              );
            })}
            {paddingBottom > 0 && (
              <tr>
                <td style={{ height: `${paddingBottom}px` }} />
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
};

function getStatusColor(status: BookingStatus): string {
  switch (status) {
    case BookingStatus.DRAFT:
      return 'bg-gray-100 text-gray-800';
    case BookingStatus.CONFIRMED:
      return 'bg-blue-100 text-blue-800';
    case BookingStatus.IN_PROGRESS:
      return 'bg-yellow-100 text-yellow-800';
    case BookingStatus.COMPLETED:
      return 'bg-green-100 text-green-800';
    case BookingStatus.CANCELLED:
      return 'bg-red-100 text-red-800';
    default:
      return 'bg-gray-100 text-gray-800';
  }
}
