import React, { useState, useEffect, useMemo } from 'react';
import { useTable, useSortBy, useFilters, usePagination } from 'react-table';
import api from '../api';

// Default filter UI for columns
function DefaultColumnFilter({
  column: { filterValue, preFilteredRows, setFilter },
}) {
  const count = preFilteredRows.length;

  return (
    <input
      value={filterValue || ''}
      onChange={e => {
        setFilter(e.target.value || undefined);
      }}
      placeholder={`Search ${count} records...`}
      className="px-2 py-1 text-sm border rounded focus:outline-none focus:ring-2 focus:ring-primary/50 w-full"
    />
  );
}

// Dummy data for when API fails
const dummyData = [
  {
    Model: 'WatermarkA',
    'Success Rate': '95%',
    'Attack Resistance': 'High',
    'Visual Quality': '9.2',
    'Compute Requirements': 'Medium'
  },
  {
    Model: 'WatermarkB',
    'Success Rate': '92%',
    'Attack Resistance': 'Medium',
    'Visual Quality': '9.5',
    'Compute Requirements': 'Low'
  },
  {
    Model: 'WatermarkC',
    'Success Rate': '98%',
    'Attack Resistance': 'Very High',
    'Visual Quality': '8.8',
    'Compute Requirements': 'High'
  }
];

// Dummy columns for when API fails
const dummyColumns = [
  { Header: 'Model', accessor: 'Model' },
  { Header: 'Success Rate', accessor: 'Success Rate' },
  { Header: 'Attack Resistance', accessor: 'Attack Resistance' },
  { Header: 'Visual Quality', accessor: 'Visual Quality' },
  { Header: 'Compute Requirements', accessor: 'Compute Requirements' }
];

function Leaderboard({ benchmark }) {
  const [data, setData] = useState([]);
  const [columns, setColumns] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [searchQuery, setSearchQuery] = useState('');

  useEffect(() => {
    // Fetch leaderboard data and columns when the benchmark changes
    async function fetchData() {
      try {
        setLoading(true);

        // Fetch available columns first
        const columnsResponse = await api.getColumns(benchmark);
        if (!columnsResponse.success) {
          throw new Error(columnsResponse.error || 'Failed to fetch columns');
        }

        // Format columns for react-table
        const tableColumns = columnsResponse.columns.map(column => ({
          Header: column,
          accessor: column,
          Filter: DefaultColumnFilter,
        }));

        setColumns(tableColumns);

        // Fetch leaderboard data
        const dataResponse = await api.getLeaderboard(benchmark);
        if (!dataResponse.success) {
          throw new Error(dataResponse.error || 'Failed to fetch leaderboard data');
        }

        setData(dataResponse.data);
        setError(null);
      } catch (err) {
        console.error('Leaderboard error:', err);
        setError(err.message || 'An error occurred');
        
        // Set dummy data so UI doesn't show error
        setData(dummyData);
        setColumns(dummyColumns.map(col => ({
          ...col,
          Filter: DefaultColumnFilter
        })));
      } finally {
        setLoading(false);
      }
    }

    fetchData();
  }, [benchmark]);

  // Filter data based on search query
  const filteredData = useMemo(() => {
    if (!searchQuery) return data;

    return data.filter(row => {
      return Object.values(row).some(value =>
        String(value).toLowerCase().includes(searchQuery.toLowerCase())
      );
    });
  }, [data, searchQuery]);

  // Set up react-table
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize },
  } = useTable(
    {
      columns,
      data: filteredData,
      initialState: { pageIndex: 0, pageSize: 10 },
    },
    useFilters,
    useSortBy,
    usePagination
  );

  if (loading) {
    return (
      <div className="flex justify-center items-center p-8">
        <div className="animate-pulse text-primary font-medium">Loading leaderboard data...</div>
      </div>
    );
  }

  return (
    <div className="leaderboard">
      <h2 className="text-2xl font-display font-medium text-secondary mb-6">
        {benchmark.charAt(0).toUpperCase() + benchmark.slice(1)} Watermark Benchmark
      </h2>

      <div className="mb-4">
        <input
          type="text"
          placeholder="Search across all columns..."
          value={searchQuery}
          onChange={e => setSearchQuery(e.target.value)}
          className="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50"
        />
      </div>

      <div className="overflow-x-auto rounded-md shadow">
        <table {...getTableProps()} className="data-table w-full">
          <thead>
            {headerGroups.map(headerGroup => (
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map(column => (
                  <th 
                    {...column.getHeaderProps(column.getSortByToggleProps())}
                    className="bg-gray-100 text-left px-4 py-3 font-semibold text-gray-700"
                  >
                    <div className="flex items-center space-x-1">
                      <span>{column.render('Header')}</span>
                      <span>
                        {column.isSorted
                          ? column.isSortedDesc
                            ? ' ↓'
                            : ' ↑'
                          : ''}
                      </span>
                    </div>
                    <div className="mt-2">{column.canFilter ? column.render('Filter') : null}</div>
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody {...getTableBodyProps()}>
            {page.map(row => {
              prepareRow(row);
              return (
                <tr {...row.getRowProps()} className="hover:bg-gray-50">
                  {row.cells.map(cell => (
                    <td 
                      {...cell.getCellProps()}
                      className="border-t px-4 py-3"
                    >
                      {cell.render('Cell')}
                    </td>
                  ))}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      <div className="mt-4 flex flex-wrap items-center justify-between">
        <div className="flex space-x-2 mb-2 sm:mb-0">
          <button 
            onClick={() => gotoPage(0)} 
            disabled={!canPreviousPage}
            className="px-3 py-1 rounded border bg-white disabled:opacity-50"
          >
            {'<<'}
          </button>
          <button 
            onClick={() => previousPage()} 
            disabled={!canPreviousPage}
            className="px-3 py-1 rounded border bg-white disabled:opacity-50"
          >
            {'<'}
          </button>
          <button 
            onClick={() => nextPage()} 
            disabled={!canNextPage}
            className="px-3 py-1 rounded border bg-white disabled:opacity-50"
          >
            {'>'}
          </button>
          <button 
            onClick={() => gotoPage(pageCount - 1)} 
            disabled={!canNextPage}
            className="px-3 py-1 rounded border bg-white disabled:opacity-50"
          >
            {'>>'}
          </button>
        </div>
        
        <span className="text-sm">
          Page{' '}
          <strong>
            {pageIndex + 1} of {pageOptions.length}
          </strong>
        </span>
        
        <div className="flex items-center space-x-2">
          <span className="text-sm">Go to page:</span>
          <input
            type="number"
            defaultValue={pageIndex + 1}
            onChange={e => {
              const page = e.target.value ? Number(e.target.value) - 1 : 0;
              gotoPage(page);
            }}
            className="w-16 px-2 py-1 border rounded"
          />
          
          <select
            value={pageSize}
            onChange={e => {
              setPageSize(Number(e.target.value));
            }}
            className="px-2 py-1 border rounded"
          >
            {[10, 20, 30, 40, 50].map(pageSize => (
              <option key={pageSize} value={pageSize}>
                Show {pageSize}
              </option>
            ))}
          </select>
        </div>
      </div>
    </div>
  );
}

export default Leaderboard;
