'use client';

import { useState, useEffect } from 'react';
import * as duckdb from '@duckdb/duckdb-wasm';

type ModelData = {
  ancestor: string;
  direct_children: string[] | null;
  all_children: string[];
  all_children_count: number;
  direct_children_count: number | null;
};

export default function Home() {
  const [allModels, setAllModels] = useState<ModelData[]>([]);
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(100);
  const [filterText, setFilterText] = useState('');
  const [isLoading, setIsLoading] = useState(true);
  const [orderBy, setOrderBy] = useState<'all_children' | 'direct_children'>('all_children');

  useEffect(() => {
    async function fetchData() {
      const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();

      // Select a bundle based on browser checks
      const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES);

      const worker_url = URL.createObjectURL(
        new Blob([`importScripts("${bundle.mainWorker!}");`], { type: 'text/javascript' })
      );

      // Instantiate the asynchronous version of DuckDB-Wasm
      const worker = new Worker(worker_url);
      const logger = new duckdb.ConsoleLogger();
      const db = new duckdb.AsyncDuckDB(logger, worker);
      await db.instantiate(bundle.mainModule, bundle.pthreadWorker);

      // Register the Parquet file using the URL
      await db.registerFileURL(
        'ancestor_children.parquet',
        `${window.location.origin}/ancestor_children.parquet`,
        duckdb.DuckDBDataProtocol.HTTP,
        false
      );

      // Execute the SQL query using the registered Parquet file
      const query = `
        SELECT
          ancestor,
          direct_children,
          all_children,
          CAST(all_children_count AS INTEGER) AS all_children_count,
          CAST(direct_children_count AS INTEGER) AS direct_children_count
        FROM 'ancestor_children.parquet'
      `;
      const conn = await db.connect();
      const result = await conn.query(query);

      // Convert the result to a JavaScript array
      const data: ModelData[] = result.toArray();

      // Close the connection and terminate the worker
      await conn.close();
      await db.terminate();

      setAllModels(data);
      setIsLoading(false);
    }
    fetchData();
  }, []);

  const filteredModels = allModels.filter((model) =>
    model.ancestor.toLowerCase().includes(filterText.toLowerCase())
  );

  const sortedModels = filteredModels.sort((a, b) => {
    if (orderBy === 'all_children') {
      return b.all_children_count - a.all_children_count;
    } else {
      return (b.direct_children_count ?? 0) - (a.direct_children_count ?? 0);
    }
  });

  const totalPages = Math.ceil(sortedModels.length / pageSize);

  const paginatedModels = sortedModels.slice(
    (currentPage - 1) * pageSize,
    currentPage * pageSize
  );

  const handleOrderByClick = (column: 'all_children' | 'direct_children') => {
    setOrderBy(column);
    setCurrentPage(1);
  };

  return (
    <main className="container mx-auto py-8 bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
      <h1 className="text-4xl font-bold mb-4">All Models</h1>
      <div className="mb-4">
        <input
          type="text"
          placeholder="Filter by model name"
          value={filterText}
          onChange={(e) => setFilterText(e.target.value)}
          className="px-4 py-2 border border-gray-300 dark:border-gray-700 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-white"
        />
      </div>
      {isLoading ? (
        <p>Loading data...</p>
      ) : paginatedModels.length > 0 ? (
        <>
          <table className="table-auto border-collapse w-full">
            <thead>
              <tr>
                <th className="px-4 py-2 bg-gray-100 dark:bg-gray-800 text-left">Model</th>
                <th
                  className="px-4 py-2 bg-gray-100 dark:bg-gray-800 text-right cursor-pointer"
                  onClick={() => handleOrderByClick('direct_children')}
                >
                  Direct Children {orderBy === 'direct_children' && '▼'}
                </th>
                <th
                  className="px-4 py-2 bg-gray-100 dark:bg-gray-800 text-right cursor-pointer"
                  onClick={() => handleOrderByClick('all_children')}
                >
                  All Children {orderBy === 'all_children' && '▼'}
                </th>
              </tr>
            </thead>
            <tbody>
              {paginatedModels.map((model, index) => (
                <tr key={index} className="border-t border-gray-200 dark:border-gray-700">
                  <td className="px-4 py-2">{model.ancestor}</td>
                  <td className="px-4 py-2 text-right">{model.direct_children_count ?? 0}</td>
                  <td className="px-4 py-2 text-right">{model.all_children_count}</td>
                </tr>
              ))}
            </tbody>
          </table>
          <div className="mt-4 flex items-center justify-between">
            <button
              onClick={() => setCurrentPage((prev) => Math.max(prev - 1, 1))}
              disabled={currentPage === 1}
              className="px-4 py-2 bg-blue-500 dark:bg-blue-600 text-white rounded-md mr-2"
            >
              Previous
            </button>
            <div className="flex items-center space-x-2">
              {currentPage > 1 && (
                <>
                  <button
                    onClick={() => setCurrentPage(1)}
                    className="px-2 py-1 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded-md"
                  >
                    1
                  </button>
                  {currentPage > 2 && <span className="text-gray-500">...</span>}
                </>
              )}
              {[...Array(5)].map((_, i) => {
                const page = currentPage + i - 2;
                if (page >= 1 && page <= totalPages) {
                  return (
                    <button
                      key={page}
                      onClick={() => setCurrentPage(page)}
                      className={`px-2 py-1 ${
                        page === currentPage
                          ? 'bg-blue-500 dark:bg-blue-600 text-white'
                          : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200'
                      } rounded-md`}
                    >
                      {page}
                    </button>
                  );
                }
                return null;
              })}
              {currentPage < totalPages && (
                <>
                  {currentPage < totalPages - 1 && <span className="text-gray-500">...</span>}
                  <button
                    onClick={() => setCurrentPage(totalPages)}
                    className="px-2 py-1 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded-md"
                  >
                    {totalPages}
                  </button>
                </>
              )}
            </div>
            <button
              onClick={() => setCurrentPage((prev) => Math.min(prev + 1, totalPages))}
              disabled={currentPage === totalPages}
              className="px-4 py-2 bg-blue-500 dark:bg-blue-600 text-white rounded-md"
            >
              Next
            </button>
          </div>
        </>
      ) : (
        <p>No data found.</p>
      )}
    </main>
  );
}
