import type { CSSProperties } from 'react'
import './TableSkeleton.scss'

type TableSkeletonCellVariant =
  | 'text'
  | 'stack'
  | 'person'
  | 'pill'
  | 'icons'
  | 'actions'
  | 'button'

export type TableSkeletonColumn = {
  width?: string
  headerWidth?: string
  lines?: number
  variant?: TableSkeletonCellVariant
}

type TableSkeletonProps = {
  className?: string
  columns: TableSkeletonColumn[]
  rows?: number
}

function getLineWidth(column: TableSkeletonColumn, rowIndex: number, lineIndex = 0) {
  if (column.width) return column.width

  const widths = ['72%', '58%', '64%', '46%']

  return widths[(rowIndex + lineIndex) % widths.length]
}

function SkeletonLine({ width }: { width?: string }) {
  return (
    <span
      className="table-skeleton__line"
      style={{ '--table-skeleton-line-width': width } as CSSProperties}
    />
  )
}

function SkeletonCell({
  column,
  rowIndex,
}: {
  column: TableSkeletonColumn
  rowIndex: number
}) {
  const variant = column.variant ?? 'text'

  if (variant === 'person') {
    return (
      <div className="table-skeleton__person">
        <span className="table-skeleton__avatar" />

        <div className="table-skeleton__stack">
          <SkeletonLine width={column.width ?? '68%'} />
          <SkeletonLine width="42%" />
        </div>
      </div>
    )
  }

  if (variant === 'stack') {
    return (
      <div className="table-skeleton__stack">
        {Array.from({ length: column.lines ?? 2 }).map((_, lineIndex) => (
          <SkeletonLine
            key={lineIndex}
            width={getLineWidth(column, rowIndex, lineIndex)}
          />
        ))}
      </div>
    )
  }

  if (variant === 'pill') {
    return <span className="table-skeleton__pill" />
  }

  if (variant === 'icons') {
    return (
      <div className="table-skeleton__icons">
        {Array.from({ length: 8 }).map((_, iconIndex) => (
          <span key={iconIndex} className="table-skeleton__icon" />
        ))}
      </div>
    )
  }

  if (variant === 'actions') {
    return (
      <div className="table-skeleton__actions">
        <span className="table-skeleton__button" />
        <span className="table-skeleton__button" />
      </div>
    )
  }

  if (variant === 'button') {
    return <span className="table-skeleton__button table-skeleton__button--single" />
  }

  return <SkeletonLine width={getLineWidth(column, rowIndex)} />
}

export function TableSkeleton({
  className = '',
  columns,
  rows = 8,
}: TableSkeletonProps) {
  return (
    <table
      className={`table-skeleton ${className}`}
      aria-label="Loading data"
      aria-busy="true"
    >
      <thead>
        <tr>
          {columns.map((column, columnIndex) => (
            <th key={columnIndex}>
              <SkeletonLine width={column.headerWidth ?? column.width ?? '54%'} />
            </th>
          ))}
        </tr>
      </thead>

      <tbody>
        {Array.from({ length: rows }).map((_, rowIndex) => (
          <tr key={rowIndex}>
            {columns.map((column, columnIndex) => (
              <td key={columnIndex}>
                <SkeletonCell column={column} rowIndex={rowIndex} />
              </td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  )
}
