"use client";

import React, { useState, useMemo } from "react";
import { cn } from "@/design-system/utils/cn";
import type { Column, DataTableProps } from "./types";

type Comparable = string | number | boolean | Date;

export function DataTable<T extends Record<string, unknown>>({
  data,
  columns,
  isLoading = false,
  emptyState,
  onRowClick,
  sortable = false,
  pagination = false,
  pageSize = 10,
  stickyHeader = true,
  className,
}: DataTableProps<T>) {
  const [sortConfig, setSortConfig] = useState<{
    key: string | null;
    direction: "asc" | "desc" | null;
  }>({ key: null, direction: null });
  const [currentPage, setCurrentPage] = useState(1);

  const sortedData = useMemo(() => {
    if (!sortConfig.key || !sortConfig.direction) {
      return data;
    }

    return [...data].sort((a, b) => {
      const key = sortConfig.key as string;
      const aValue = a[key] as Comparable;
      const bValue = b[key] as Comparable;

      if (aValue === bValue) return 0;

      const comparison = aValue < bValue ? -1 : 1;
      return sortConfig.direction === "asc" ? comparison : -comparison;
    });
  }, [data, sortConfig]);

  const paginatedData = useMemo(() => {
    if (!pagination) return sortedData;

    const startIndex = (currentPage - 1) * pageSize;
    const endIndex = startIndex + pageSize;
    return sortedData.slice(startIndex, endIndex);
  }, [sortedData, pagination, currentPage, pageSize]);

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

  const handleSort = (key: string) => {
    setSortConfig((prev) => {
      if (prev.key === key) {
        if (prev.direction === "asc") {
          return { key, direction: "desc" };
        }
        if (prev.direction === "desc") {
          return { key: null, direction: null };
        }
      }
      return { key, direction: "asc" };
    });
  };

  const getAlignmentClass = (align?: "left" | "center" | "right") => {
    switch (align) {
      case "center":
        return "text-center";
      case "right":
        return "text-right";
      default:
        return "text-left";
    }
  };

  const renderSkeleton = () => (
    <div className="animate-pulse">
      <div className="space-y-2">
        {Array.from({ length: 5 }).map((_, i) => (
          <div
            key={i}
            className="flex space-x-4 border-b border-[#2c2c2c] py-3"
          >
            {columns.map((col) => (
              <div
                key={`${col.key}-skeleton-${i}`}
                className="h-4 bg-[#2c2c2c] rounded"
                style={{ width: col.width || "auto" }}
              />
            ))}
          </div>
        ))}
      </div>
    </div>
  );

  const renderEmptyState = () => {
    if (emptyState) {
      return (
        <div className="py-12 text-center text-[#a0a0a0]">{emptyState}</div>
      );
    }
    return (
      <div className="py-12 text-center text-[#a0a0a0]">
        <p className="text-sm">No data available</p>
      </div>
    );
  };

  return (
    <div className={cn("w-full", className)}>
      {/* Table */}
      <div className="overflow-x-auto">
        <table className="w-full">
          {stickyHeader && (
            <thead className={cn("sticky top-0 z-10", "bg-[#0d0d0d]")}>
              <tr>
                {columns.map((column) => (
                  <th
                    key={column.key}
                    className={cn(
                      "px-4 py-3",
                      "bg-[#1e1e1e]",
                      "text-[#a0a0a0]",
                      "uppercase tracking-widest text-xs font-medium",
                      getAlignmentClass(column.align),
                      sortable &&
                        column.sortable !== false &&
                        "cursor-pointer hover:text-white transition-colors",
                      "select-none",
                    )}
                    style={{ width: column.width }}
                    onClick={
                      sortable && column.sortable !== false
                        ? () => handleSort(column.key)
                        : undefined
                    }
                  >
                    <div className="flex items-center gap-2">
                      {column.header}
                      {sortable && column.sortable !== false && (
                        <span className="flex flex-col">
                          <span
                            className={cn(
                              "text-[8px] leading-none",
                              sortConfig.key === column.key &&
                                sortConfig.direction === "asc"
                                ? "text-white"
                                : "text-[#404040]",
                            )}
                          >
                            ▲
                          </span>
                          <span
                            className={cn(
                              "text-[8px] leading-none",
                              sortConfig.key === column.key &&
                                sortConfig.direction === "desc"
                                ? "text-white"
                                : "text-[#404040]",
                            )}
                          >
                            ▼
                          </span>
                        </span>
                      )}
                    </div>
                  </th>
                ))}
              </tr>
            </thead>
          )}

          <tbody>
            {isLoading ? (
              <tr>
                <td colSpan={columns.length}>{renderSkeleton()}</td>
              </tr>
            ) : paginatedData.length === 0 ? (
              <tr>
                <td colSpan={columns.length}>{renderEmptyState()}</td>
              </tr>
            ) : (
              paginatedData.map((row, rowIndex) => (
                <tr
                  key={`row-${rowIndex}`}
                  className={cn(
                    "hover:bg-[#1e1e1e] border-b border-[#2c2c2c] transition-colors",
                    onRowClick && "cursor-pointer",
                  )}
                  onClick={() => onRowClick?.(row)}
                >
                  {columns.map((column) => (
                    <td
                      key={`${column.key}-${rowIndex}`}
                      className={cn(
                        "px-4 py-3 text-sm text-[#e1e1e1]",
                        getAlignmentClass(column.align),
                      )}
                    >
                      {column.cell(row)}
                    </td>
                  ))}
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>

      {/* Pagination */}
      {pagination && !isLoading && paginatedData.length > 0 && (
        <div className="flex items-center justify-between px-4 py-3 border-t border-[#2c2c2c]">
          <div className="text-sm text-[#a0a0a0]">
            Showing {(currentPage - 1) * pageSize + 1} to{" "}
            {Math.min(currentPage * pageSize, sortedData.length)} of{" "}
            {sortedData.length} entries
          </div>
          <div className="flex items-center gap-2">
            <button
              onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
              disabled={currentPage === 1}
              className={cn(
                "px-3 py-1 text-sm rounded border border-[#2c2c2c]",
                "hover:bg-[#2c2c2c] disabled:opacity-50 disabled:cursor-not-allowed",
                "transition-colors",
              )}
            >
              Previous
            </button>
            {Array.from({ length: totalPages }).map((_, i) => {
              const pageNum = i + 1;
              const isCurrentPage = pageNum === currentPage;
              const showPage =
                pageNum === 1 ||
                pageNum === totalPages ||
                (pageNum >= currentPage - 1 && pageNum <= currentPage + 1);

              if (!showPage) {
                if (
                  pageNum === currentPage - 2 ||
                  pageNum === currentPage + 2
                ) {
                  return (
                    <span
                      key={`ellipsis-${pageNum}`}
                      className="text-[#a0a0a0]"
                    >
                      ...
                    </span>
                  );
                }
                return null;
              }

              return (
                <button
                  key={pageNum}
                  onClick={() => setCurrentPage(pageNum)}
                  className={cn(
                    "px-3 py-1 text-sm rounded border",
                    isCurrentPage
                      ? "bg-blue-600 border-blue-600 text-white"
                      : "border-[#2c2c2c] hover:bg-[#2c2c2c]",
                    "transition-colors",
                  )}
                >
                  {pageNum}
                </button>
              );
            })}
            <button
              onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
              disabled={currentPage === totalPages}
              className={cn(
                "px-3 py-1 text-sm rounded border border-[#2c2c2c]",
                "hover:bg-[#2c2c2c] disabled:opacity-50 disabled:cursor-not-allowed",
                "transition-colors",
              )}
            >
              Next
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
