import { ChevronDown, ChevronUp } from 'lucide-react';

import { useId, useState } from 'react';

import { Button } from '@/Components/ui/button';
import { formatDecimal, formatNumber } from '@/lib/format';
import { cn } from '@/lib/utils';

interface ColumnDefinition {
  key: string;
  label: string;
}

interface ChartDataTableProps {
  data: Array<Record<string, unknown>>;
  columns: ColumnDefinition[];
  caption: string;
  className?: string;
}

/**
 * ChartDataTable: A screen-reader accessible companion to charts
 * Provides tabular data representation that's hidden visually but available to assistive technologies
 * Also includes a visible toggle button to reveal the data table
 */
export function ChartDataTable({
  data,
  columns,
  caption,
  className,
}: ChartDataTableProps) {
  const [isExpanded, setIsExpanded] = useState(false);
  const uid = useId();
  const visualTableId = `${uid}-visual`;
  const srTableId = `${uid}-sr`;

  if (!data || data.length === 0) {
    return null;
  }

  return (
    <div className={cn('mt-6 space-y-4', className)}>
      {/* Toggle Button - Visible to all users */}
      <div>
        <Button
          variant="outline"
          size="sm"
          onClick={() => setIsExpanded(!isExpanded)}
          aria-expanded={isExpanded}
          aria-controls={visualTableId}
          className="gap-2"
        >
          {isExpanded ? (
            <>
              <ChevronUp className="h-4 w-4" />
              Hide data table
            </>
          ) : (
            <>
              <ChevronDown className="h-4 w-4" />
              Show data table
            </>
          )}
        </Button>
      </div>

      {/* Data Table - Visible only when expanded */}
      <div id={visualTableId}>
        {isExpanded && (
          <div className="overflow-x-auto border rounded-lg">
            <table className="w-full text-sm border-collapse">
              <caption className="sr-only">{caption}</caption>
              <thead className="bg-muted border-b sticky top-0">
                <tr>
                  {columns.map((column) => (
                    <th
                      key={column.key}
                      className="px-4 py-2 text-left font-semibold text-foreground border-r last:border-r-0"
                      scope="col"
                    >
                      {column.label}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {data.map((row, rowIndex) => (
                  <tr
                    key={rowIndex}
                    className="border-b last:border-b-0 hover:bg-muted/50 transition-colors"
                  >
                    {columns.map((column) => (
                      <td
                        key={`${rowIndex}-${column.key}`}
                        className="px-4 py-2 text-foreground border-r last:border-r-0"
                      >
                        {formatValue(row[column.key])}
                      </td>
                    ))}
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {/* Visually Hidden Table - Accessible to screen readers when visual table is collapsed; hidden when expanded to prevent duplicate announcements */}
      <div className="sr-only" id={srTableId} aria-hidden={isExpanded} aria-live="polite" aria-atomic="true">
        <table role="table" aria-label={caption}>
          <caption>{caption}</caption>
          <thead>
            <tr>
              {columns.map((column) => (
                <th key={column.key} scope="col">
                  {column.label}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {data.map((row, rowIndex) => (
              <tr key={rowIndex}>
                {columns.map((column) => (
                  <td key={`${rowIndex}-${column.key}`}>{formatValue(row[column.key])}</td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

/**
 * Format values for display in the table
 * Handles numbers with thousands separators and percentages
 */
function formatValue(value: unknown): string {
  if (value === null || value === undefined) {
    return '—';
  }

  if (typeof value === 'number') {
    // Format numbers with thousands separators
    if (Number.isInteger(value)) {
      return formatNumber(value);
    }
    // Format decimals to 2 places
    return formatDecimal(value);
  }

  if (typeof value === 'string') {
    return value;
  }

  if (typeof value === 'boolean') {
    return value ? 'Yes' : 'No';
  }

  return String(value);
}
