import React from 'react';
import { ArrowUpDown, ArrowUp, ArrowDown } from 'lucide-react';
import type { VisibilityMode } from '@/hooks/useTableVisibility';
import { useMediaQuery } from '@/hooks/useMediaQuery';

export interface ColumnDef<T> {
  key: string;
  label: string;
  render: (item: T) => React.ReactNode;
  sortable?: boolean;
  visibilityLevel: VisibilityMode;
}

export interface RowGroup<T> {
  label: string;
  rows: T[];
}

interface EntityTableProps<T extends { id: number }> {
  columns: ColumnDef<T>[];
  groups: RowGroup<T>[];
  pinnedRows: T[];
  pinnedLabel: string;
  showPinned: boolean;
  selectedId: number | null;
  onRowClick: (id: number) => void;
  sortKey: string;
  sortDir: 'asc' | 'desc';
  onSort: (key: string) => void;
  visibilityMode: VisibilityMode;
  loading?: boolean;
  mobileCardRender?: (item: T) => React.ReactNode;
}

const LEVEL_ORDER: VisibilityMode[] = ['essential', 'filtered', 'all'];

function isVisible(colLevel: VisibilityMode, mode: VisibilityMode): boolean {
  return LEVEL_ORDER.indexOf(colLevel) <= LEVEL_ORDER.indexOf(mode);
}

function SkeletonRow({ colCount }: { colCount: number }) {
  return (
    <tr className="border-b border-border/50">
      {Array.from({ length: colCount }).map((_, i) => (
        <td key={i} className="px-3 py-2.5">
          <div className="animate-pulse rounded-md bg-muted h-4 w-full" />
        </td>
      ))}
    </tr>
  );
}

function SortIcon({
  sortKey,
  sortDir,
  colKey,
}: {
  sortKey: string;
  sortDir: 'asc' | 'desc';
  colKey: string;
}) {
  if (sortKey !== colKey) return <ArrowUpDown className="h-3.5 w-3.5 ml-1 opacity-40" />;
  return sortDir === 'asc' ? (
    <ArrowUp className="h-3.5 w-3.5 ml-1" />
  ) : (
    <ArrowDown className="h-3.5 w-3.5 ml-1" />
  );
}

function DataRow<T extends { id: number }>({
  item,
  visibleColumns,
  selectedId,
  onRowClick,
}: {
  item: T;
  visibleColumns: ColumnDef<T>[];
  selectedId: number | null;
  onRowClick: (id: number) => void;
}) {
  return (
    <tr
      className={`border-b border-border/50 cursor-pointer hover:bg-card-elevated transition-colors duration-150 outline-none focus-visible:ring-1 focus-visible:ring-ring ${
        selectedId === item.id ? 'bg-accent/10' : ''
      }`}
      onClick={() => onRowClick(item.id)}
      onKeyDown={(e) => {
        if (e.key === 'Enter' || e.key === ' ') {
          e.preventDefault();
          onRowClick(item.id);
        }
      }}
      tabIndex={0}
      role="row"
      aria-selected={selectedId === item.id}
    >
      {visibleColumns.map((col) => (
        <td key={col.key} className="px-3 py-2.5 text-sm">
          {col.render(item)}
        </td>
      ))}
    </tr>
  );
}

function SectionHeader({ label, colCount }: { label: string; colCount: number }) {
  return (
    <tr>
      <td
        colSpan={colCount}
        className="px-3 pt-4 pb-1.5 text-[11px] uppercase tracking-wider text-muted-foreground font-medium"
      >
        {label}
      </td>
    </tr>
  );
}

export function EntityTable<T extends { id: number }>({
  columns,
  groups,
  pinnedRows,
  pinnedLabel,
  showPinned,
  selectedId,
  onRowClick,
  sortKey,
  sortDir,
  onSort,
  visibilityMode,
  loading = false,
  mobileCardRender,
}: EntityTableProps<T>) {
  const visibleColumns = columns.filter((col) => isVisible(col.visibilityLevel, visibilityMode));
  const colCount = visibleColumns.length;
  const showPinnedSection = showPinned && pinnedRows.length > 0;
  const isMobile = useMediaQuery('(max-width: 767px)');

  if (isMobile && mobileCardRender) {
    return (
      <div className="space-y-2">
        {loading ? (
          Array.from({ length: 6 }).map((_, i) => (
            <div key={i} className="animate-pulse rounded-lg bg-card border border-border p-4 h-20" />
          ))
        ) : (
          <>
            {showPinnedSection && (
              <>
                <p className="text-[11px] uppercase tracking-wider text-muted-foreground font-medium pt-2">{pinnedLabel}</p>
                {pinnedRows.map((item) => (
                  <div key={item.id} onClick={() => onRowClick(item.id)} className="cursor-pointer" role="button" tabIndex={0} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onRowClick(item.id); } }}>
                    {mobileCardRender(item)}
                  </div>
                ))}
              </>
            )}
            {groups.map((group) => (
              <React.Fragment key={group.label}>
                {group.rows.length > 0 && (
                  <>
                    <p className="text-[11px] uppercase tracking-wider text-muted-foreground font-medium pt-2">{group.label}</p>
                    {group.rows.map((item) => (
                      <div key={item.id} onClick={() => onRowClick(item.id)} className="cursor-pointer" role="button" tabIndex={0} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onRowClick(item.id); } }}>
                        {mobileCardRender(item)}
                      </div>
                    ))}
                  </>
                )}
              </React.Fragment>
            ))}
          </>
        )}
      </div>
    );
  }

  return (
    <div className="w-full">
      <table className="w-full border-collapse">
        <thead>
          <tr className="border-b border-border">
            {visibleColumns.map((col) => (
              <th
                key={col.key}
                className="px-3 py-2 text-left text-[11px] uppercase tracking-wider text-muted-foreground font-medium"
              >
                {col.sortable ? (
                  <button
                    type="button"
                    onClick={() => onSort(col.key)}
                    aria-label={`Sort by ${col.label}`}
                    className="flex items-center hover:text-foreground transition-colors duration-150"
                  >
                    {col.label}
                    <SortIcon sortKey={sortKey} sortDir={sortDir} colKey={col.key} />
                  </button>
                ) : (
                  col.label
                )}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {loading ? (
            Array.from({ length: 6 }).map((_, i) => <SkeletonRow key={i} colCount={colCount} />)
          ) : (
            <>
              {showPinnedSection && (
                <>
                  <SectionHeader label={pinnedLabel} colCount={colCount} />
                  {pinnedRows.map((item) => (
                    <DataRow
                      key={item.id}
                      item={item}
                      visibleColumns={visibleColumns}
                      selectedId={selectedId}
                      onRowClick={onRowClick}
                    />
                  ))}
                </>
              )}
              {groups.map((group) => (
                <React.Fragment key={group.label}>
                  {group.rows.length > 0 && (
                    <>
                      <SectionHeader label={group.label} colCount={colCount} />
                      {group.rows.map((item) => (
                        <DataRow
                          key={item.id}
                          item={item}
                          visibleColumns={visibleColumns}
                          selectedId={selectedId}
                          onRowClick={onRowClick}
                        />
                      ))}
                    </>
                  )}
                </React.Fragment>
              ))}
            </>
          )}
        </tbody>
      </table>
    </div>
  );
}
