'use client'

/**
 * MembersTable — headless members list. Renders avatar + name + email +
 * role badge + actions per row. When `canManage` is true the row shows a
 * RoleSelector (calls onChangeRole) + a Remove button (calls onRemove).
 *
 * Pagination is intentionally absent — the backend endpoint at
 * /api/v1/teams/{id}/members returns the full list. SSP support is a
 * follow-up bead. startsim-o7s.
 */

import * as React from 'react'
import { RoleSelector } from './RoleSelector'
import {
  userDisplayName,
  userInitials,
  type MemberRow,
  type TeamRole,
} from './types'
import {
  MEMBERS_TABLE_DEFAULTS,
  type MembersTableClassNames,
} from './members-table-default-class-names'

export interface MembersTableProps {
  members: MemberRow[]
  /**
   * When true, expose the role selector + remove button. Apps should pass
   * `canManage = isAdmin || isOwner` derived from useMembership().
   */
  canManage?: boolean
  onChangeRole?: (userId: string, role: TeamRole) => void | Promise<void>
  onRemove?: (userId: string) => void | Promise<void>
  /** Custom empty-state slot. Defaults to a generic "No members yet" cell. */
  emptyState?: React.ReactNode
  classNames?: MembersTableClassNames
  /** Restrict role-selector options (e.g. hide 'owner' when caller isn't owner). */
  availableRoles?: TeamRole[]
  /**
   * The signed-in user's id. When it matches a row, that row is badged "You" —
   * otherwise the owner is an anonymous line sitting next to a live Remove
   * button with nothing marking it as themselves.
   */
  currentUserId?: string
}

const ROLE_LABEL: Record<TeamRole, string> = {
  owner: 'Owner',
  admin: 'Admin',
  member: 'Member',
  viewer: 'Viewer',
}

export function MembersTable({
  members,
  canManage = false,
  onChangeRole,
  onRemove,
  emptyState,
  classNames,
  availableRoles,
  currentUserId,
}: MembersTableProps) {
  const cls = { ...MEMBERS_TABLE_DEFAULTS, ...(classNames ?? {}) }
  // Role + actions hug their content so the Member column takes the slack —
  // one shared cell class used to split the table down the middle and leave
  // the controls floating in a gap.
  const tight = (base: string, extra: string) => `${base} ${extra}`.trim()

  return (
    <div className={cls.root}>
      <table className={cls.table}>
        <thead className={cls.thead}>
          <tr className={cls.headerRow}>
            <th className={cls.th} scope="col">Member</th>
            <th className={tight(cls.th, cls.tightColumn)} scope="col">Role</th>
            {canManage && (
              <th className={tight(cls.th, cls.tightColumn)} scope="col" aria-label="Actions" />
            )}
          </tr>
        </thead>
        <tbody className={cls.tbody}>
          {members.length === 0 && (
            <tr>
              <td className={cls.emptyRow} colSpan={canManage ? 3 : 2}>
                {emptyState ?? 'No members yet.'}
              </td>
            </tr>
          )}
          {members.map((m) => {
            const displayName = userDisplayName(m.user) || m.userId
            // Members with no name fall back to their email, so printing the
            // email underneath stacked the same string on itself.
            const secondary = m.user?.email && m.user.email !== displayName ? m.user.email : null
            const isSelf = !!currentUserId && m.userId === currentUserId
            return (
            <tr key={m.id} className={cls.row}>
              <td className={cls.cell}>
                <div className="flex items-center gap-3">
                  {m.user?.avatarUrl ? (
                    <img
                      src={m.user.avatarUrl}
                      alt=""
                      className={cls.avatar}
                      style={{ objectFit: 'cover' }}
                    />
                  ) : (
                    <span className={cls.avatar} aria-hidden="true">
                      {userInitials(m.user)}
                    </span>
                  )}
                  <div className="flex min-w-0 flex-col">
                    <span className="flex items-center gap-2">
                      <span className={cls.name}>{displayName}</span>
                      {isSelf && <span className={cls.selfBadge}>You</span>}
                    </span>
                    {secondary && <span className={cls.email}>{secondary}</span>}
                  </div>
                </div>
              </td>
              <td className={tight(cls.cell, cls.tightColumn)}>
                {canManage && onChangeRole ? (
                  <RoleSelector
                    value={m.role}
                    onChange={(role) => onChangeRole(m.userId, role)}
                    availableRoles={availableRoles}
                  />
                ) : (
                  <span className={cls.roleBadge}>{ROLE_LABEL[m.role]}</span>
                )}
              </td>
              {canManage && (
                <td className={tight(cls.cell, cls.tightColumn)}>
                  <div className={cls.actions}>
                    {onRemove && (
                      <button
                        type="button"
                        className={cls.removeButton}
                        onClick={() => onRemove(m.userId)}
                      >
                        Remove
                      </button>
                    )}
                  </div>
                </td>
              )}
            </tr>
            )
          })}
        </tbody>
      </table>
    </div>
  )
}
