"use client";

import {
  useReactTable,
  getCoreRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  flexRender,
  ColumnDef,
  SortingState,
  HeaderContext,
  CellContext,
} from "@tanstack/react-table";
import { useState, useMemo, useRef, useEffect } from "react";
import { 
  ChevronLeft, 
  ChevronRight, 
  ArrowUpDown, 
  ChevronsLeft, 
  ChevronsRight, 
  Download, 
  FileJson, 
  FileSpreadsheet, 
  ChevronDown 
} from "lucide-react";

type DataRow = Record<string, unknown>;

interface ResultTableProps {
  data: DataRow[];
}

export function ResultTable({ data }: ResultTableProps) {
  const [sorting, setSorting] = useState<SortingState>([]);
  const [pagination, setPagination] = useState({
    pageIndex: 0,
    pageSize: 10,
  });
  const [isExportOpen, setIsExportOpen] = useState(false);
  const exportMenuRef = useRef<HTMLDivElement>(null);

  // Close dropdown when clicking outside
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (exportMenuRef.current && !exportMenuRef.current.contains(event.target as Node)) {
        setIsExportOpen(false);
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  const columns = useMemo<ColumnDef<DataRow>[]>(() => {
    if (!data || data.length === 0) return [];
    
    // Add Row Number Column
    const rowNumberColumn: ColumnDef<DataRow> = {
      id: 'rowNumber',
      header: 'Row',
      cell: (info) => {
        const { pageIndex, pageSize } = info.table.getState().pagination;
        const pageRows = info.table.getRowModel().rows;
        const indexInPage = pageRows.findIndex((r) => r.id === info.row.id);
        const safeIndexInPage = indexInPage >= 0 ? indexInPage : 0;
        return pageIndex * pageSize + safeIndexInPage + 1;
      },
      enableSorting: false,
    };

    const keys = Object.keys(data[0]);
    const dataColumns = keys.map((key) => ({
      accessorKey: key,
      header: ({ column }: HeaderContext<DataRow, unknown>) => {
        return (
          <button
            className="flex items-center gap-1.5 font-semibold text-warm-600 dark:text-warm-300 
                     hover:text-warm-800 dark:hover:text-cream-100 transition-colors group"
            onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
          >
            <span>{key}</span>
            <ArrowUpDown className="w-3.5 h-3.5 opacity-40 group-hover:opacity-100 transition-opacity" />
          </button>
        );
      },
      cell: (info: CellContext<DataRow, unknown>) => {
        const val = info.getValue();
        if (val && typeof val === 'object' && 'value' in val) return String((val as { value: unknown }).value);
        if (typeof val === 'object' && val !== null) return JSON.stringify(val);
        
        // Format numbers nicely
        if (typeof val === 'number') {
          return new Intl.NumberFormat('en-US', {
            maximumFractionDigits: 2,
          }).format(val);
        }
        
        return String(val ?? '—');
      }
    }));

    return [rowNumberColumn, ...dataColumns];
  }, [data]);

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
    onSortingChange: setSorting,
    onPaginationChange: setPagination,
    state: {
      sorting,
      pagination,
    },
  });

  const downloadCSV = () => {
    if (!data || data.length === 0) return;
    
    const headers = Object.keys(data[0]);
    const csvContent = [
      headers.join(','),
      ...data.map(row => headers.map(header => {
        const val = row[header];
        const stringVal = typeof val === 'object' ? JSON.stringify(val) : String(val ?? '');
        // Escape quotes and wrap in quotes if necessary
        return `"${stringVal.replace(/"/g, '""')}"`;
      }).join(','))
    ].join('\n');

    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `query_results_${new Date().toISOString().slice(0,10)}.csv`;
    link.click();
    setIsExportOpen(false);
  };

  const downloadJSON = () => {
    if (!data || data.length === 0) return;
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `query_results_${new Date().toISOString().slice(0,10)}.json`;
    link.click();
    setIsExportOpen(false);
  };

  if (!data || data.length === 0) {
    return (
      <div className="p-8 text-center text-warm-400 dark:text-warm-500">
        <p className="text-sm">No data available</p>
      </div>
    );
  }

  const totalPages = table.getPageCount();
  const { pageIndex, pageSize } = table.getState().pagination;
  const currentPage = pageIndex + 1;
  const pageRowsCount = table.getRowModel().rows.length;
  const startRow = pageRowsCount === 0 ? 0 : pageIndex * pageSize + 1;
  const endRow = pageRowsCount === 0 ? 0 : startRow + pageRowsCount - 1;
  const pageSizeOptions = [10, 30, 50, 100, 200];

  return (
    <div className="w-full bg-white dark:bg-warm-800 rounded-xl border border-cream-300 dark:border-warm-700 overflow-hidden shadow-warm-sm">
      {/* Toolbar */}
      <div className="flex flex-col sm:flex-row sm:items-center justify-between border-b border-cream-200 dark:border-warm-700 bg-cream-50 dark:bg-warm-800">
        {/* Tabs */}
        <div className="flex items-center">
          <button
            className="px-4 py-3 text-xs font-bold uppercase tracking-wide text-accent dark:text-accent-300 border-b-2 border-accent dark:border-accent-300"
          >
            Query Results
          </button>
        </div>

        {/* Actions */}
        <div className="flex items-center gap-2 p-2 border-t sm:border-t-0 border-cream-200 dark:border-warm-700">
           <div className="relative" ref={exportMenuRef}>
             <button
               onClick={() => setIsExportOpen(!isExportOpen)}
               className="flex items-center gap-2 px-3 py-1.5 text-xs font-medium text-warm-700 dark:text-warm-200 
                        bg-white dark:bg-warm-700 border border-cream-300 dark:border-warm-600 rounded-lg 
                        hover:bg-cream-100 dark:hover:bg-warm-600 transition-colors shadow-warm-sm"
             >
               <Download className="w-3.5 h-3.5" />
               <span>Save results</span>
               <ChevronDown className="w-3 h-3 text-warm-400" />
             </button>

             {isExportOpen && (
               <div className="absolute right-0 mt-1 w-48 bg-white dark:bg-warm-800 rounded-xl shadow-warm-lg border border-cream-200 dark:border-warm-700 z-50 animate-fade-in">
                 <div className="py-1">
                   <button
                     onClick={downloadCSV}
                     className="flex items-center gap-3 w-full px-4 py-2.5 text-xs text-left text-warm-700 dark:text-warm-200 hover:bg-cream-100 dark:hover:bg-warm-700/50 transition-colors"
                   >
                     <FileSpreadsheet className="w-3.5 h-3.5 text-green-600 dark:text-green-400" />
                     CSV (local file)
                   </button>
                   <button
                     onClick={downloadJSON}
                     className="flex items-center gap-3 w-full px-4 py-2.5 text-xs text-left text-warm-700 dark:text-warm-200 hover:bg-cream-100 dark:hover:bg-warm-700/50 transition-colors"
                   >
                     <FileJson className="w-3.5 h-3.5 text-accent dark:text-accent-300" />
                     JSON (local file)
                   </button>
                 </div>
               </div>
             )}
           </div>
        </div>
      </div>

      {/* Table */}
      <div className="overflow-x-auto scrollbar-thin">
        <table className="w-full text-sm text-left">
          <thead className="text-xs text-warm-500 dark:text-warm-400 uppercase bg-cream-100 dark:bg-warm-800/50 border-b border-cream-200 dark:border-warm-700">
            {table.getHeaderGroups().map((headerGroup) => (
              <tr key={headerGroup.id}>
                {headerGroup.headers.map((header) => (
                  <th 
                    key={header.id} 
                    className="px-4 py-3 font-semibold whitespace-nowrap first:w-16 first:text-center"
                  >
                    {header.isPlaceholder
                      ? null
                      : flexRender(
                          header.column.columnDef.header,
                          header.getContext()
                        )}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody className="divide-y divide-cream-100 dark:divide-warm-700">
            {table.getRowModel().rows.map((row, index) => (
              <tr
                key={row.id}
                className={[
                  index % 2 === 0 ? 'bg-white dark:bg-warm-800' : 'bg-cream-50 dark:bg-warm-800/70',
                  'hover:bg-cream-100 dark:hover:bg-warm-700/50 transition-colors',
                ].join(' ')}
              >
                {row.getVisibleCells().map((cell) => (
                  <td 
                    key={cell.id} 
                    className={`
                      px-4 py-2.5 whitespace-nowrap text-xs font-mono
                      ${cell.column.id === 'rowNumber' 
                        ? 'text-warm-400 dark:text-warm-500 text-center select-none' 
                        : 'text-warm-700 dark:text-warm-200'}
                    `}
                  >
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      
      {/* Pagination */}
      <div className="flex items-center justify-between px-4 py-2.5 border-t border-cream-200 dark:border-warm-700 bg-cream-50 dark:bg-warm-800/50 text-xs">
        <div className="flex items-center gap-4 text-warm-500 dark:text-warm-400">
          <label className="flex items-center gap-2">
            <span>Results per page:</span>
            <select
              className="h-7 rounded-md border border-cream-300 bg-white px-2 text-xs text-warm-700 shadow-warm-sm
                         focus:outline-none focus:ring-2 focus:ring-accent/30 dark:border-warm-600 dark:bg-warm-700 dark:text-warm-100"
              value={pageSize}
              onChange={(e) => table.setPageSize(Number(e.target.value))}
            >
              {pageSizeOptions.map((size) => (
                <option key={size} value={size}>
                  {size}
                </option>
              ))}
            </select>
          </label>

          <span>
            <span className="font-semibold text-warm-800 dark:text-cream-100">{startRow}-{endRow}</span> of{' '}
            <span className="font-semibold text-warm-800 dark:text-cream-100">{data.length}</span>
          </span>
        </div>
        
        {totalPages > 1 && (
          <div className="flex items-center gap-1">
             <span className="mr-2 text-warm-500 dark:text-warm-400">
              Page {currentPage} of {totalPages}
            </span>

            {/* Pagination Controls */}
            <div className="flex items-center rounded-lg border border-cream-300 dark:border-warm-600 bg-white dark:bg-warm-700 shadow-warm-sm overflow-hidden">
              <button
                className="p-1.5 hover:bg-cream-100 dark:hover:bg-warm-600 disabled:opacity-30 transition-colors"
                onClick={() => table.setPageIndex(0)}
                disabled={!table.getCanPreviousPage()}
              >
                <ChevronsLeft className="w-4 h-4 text-warm-600 dark:text-warm-300" />
              </button>
              <div className="w-px h-7 bg-cream-200 dark:bg-warm-600" />
              <button
                className="p-1.5 hover:bg-cream-100 dark:hover:bg-warm-600 disabled:opacity-30 transition-colors"
                onClick={() => table.previousPage()}
                disabled={!table.getCanPreviousPage()}
              >
                <ChevronLeft className="w-4 h-4 text-warm-600 dark:text-warm-300" />
              </button>
              <div className="w-px h-7 bg-cream-200 dark:bg-warm-600" />
              <button
                className="p-1.5 hover:bg-cream-100 dark:hover:bg-warm-600 disabled:opacity-30 transition-colors"
                onClick={() => table.nextPage()}
                disabled={!table.getCanNextPage()}
              >
                <ChevronRight className="w-4 h-4 text-warm-600 dark:text-warm-300" />
              </button>
              <div className="w-px h-7 bg-cream-200 dark:bg-warm-600" />
              <button
                className="p-1.5 hover:bg-cream-100 dark:hover:bg-warm-600 disabled:opacity-30 transition-colors"
                onClick={() => table.setPageIndex(totalPages - 1)}
                disabled={!table.getCanNextPage()}
              >
                <ChevronsRight className="w-4 h-4 text-warm-600 dark:text-warm-300" />
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
