'use client'

import React, { useEffect, useState } from 'react'
import { Awareness } from 'y-protocols/awareness'

import {
  summarisePresence,
  type CollaborationStatus,
  type PresenceSnapshot,
} from '../lib/collaboration-provider.js'

export interface PresenceChipsProps {
  /** Awareness instance returned from `createCollaborationProvider`. */
  awareness: Awareness
  /**
   * Optional connection status. When provided the strip renders a small
   * status pill (Connected / Connecting / Disconnected) on the left side.
   */
  status?: CollaborationStatus
  /**
   * Hide the local user from the strip. Defaults to `true` — the local user
   * already knows they're editing.
   */
  hideSelf?: boolean
  /** Max chips to show before collapsing to "+N". Defaults to 5. */
  maxVisible?: number
  className?: string
}

/**
 * Small avatar / initials strip showing who else is currently editing the
 * document. Subscribes to the supplied `Awareness` instance for live
 * updates.
 *
 * The component is intentionally stateless about transport — it only reads
 * from Awareness and `status`. Wiring is the caller's job.
 */
export function PresenceChips({
  awareness,
  status,
  hideSelf = true,
  maxVisible = 5,
  className,
}: PresenceChipsProps) {
  const [snapshot, setSnapshot] = useState<PresenceSnapshot>(() => summarisePresence(awareness))

  useEffect(() => {
    const update = () => {
      setSnapshot(summarisePresence(awareness))
    }
    update()
    awareness.on('update', update)
    awareness.on('change', update)
    return () => {
      awareness.off('update', update)
      awareness.off('change', update)
    }
  }, [awareness])

  const visible = hideSelf
    ? snapshot.users.filter((u) => u.clientId !== snapshot.selfClientId)
    : snapshot.users
  const overflow = Math.max(0, visible.length - maxVisible)
  const shown = visible.slice(0, maxVisible)

  return (
    <div
      className={`inline-flex items-center gap-1.5 text-xs ${className ?? ''}`}
      data-testid="presence-chips"
    >
      {status && <StatusPill status={status} />}
      {shown.length === 0 && status !== 'connecting' && (
        <span className="text-gray-500" data-testid="presence-empty">
          You're the only one here
        </span>
      )}
      {shown.map(({ clientId, user }) => (
        <Chip key={clientId} name={user.name} color={user.color} avatarUrl={user.avatarUrl} />
      ))}
      {overflow > 0 && (
        <span
          className="rounded-full bg-gray-100 px-2 py-0.5 text-gray-700"
          data-testid="presence-overflow"
        >
          +{overflow}
        </span>
      )}
    </div>
  )
}

function StatusPill({ status }: { status: CollaborationStatus }) {
  const palette: Record<CollaborationStatus, { dot: string; label: string; text: string }> = {
    connected: { dot: 'bg-emerald-500', label: 'Live', text: 'text-emerald-700' },
    connecting: { dot: 'bg-amber-400 animate-pulse', label: 'Connecting', text: 'text-amber-700' },
    disconnected: { dot: 'bg-gray-300', label: 'Offline', text: 'text-gray-500' },
  }
  const cfg = palette[status]
  return (
    <span
      className={`inline-flex items-center gap-1 rounded-full bg-gray-50 px-2 py-0.5 ${cfg.text}`}
      data-testid={`presence-status-${status}`}
    >
      <span className={`h-1.5 w-1.5 rounded-full ${cfg.dot}`} />
      {cfg.label}
    </span>
  )
}

function Chip({ name, color, avatarUrl }: { name: string; color: string; avatarUrl?: string }) {
  const initials = nameToInitials(name)
  return (
    <span
      className="inline-flex items-center gap-1 rounded-full bg-white px-1.5 py-0.5 ring-1 ring-gray-200"
      title={name}
      data-testid="presence-chip"
    >
      {avatarUrl ? (
        <img
          src={avatarUrl}
          alt=""
          className="h-4 w-4 rounded-full object-cover"
          style={{ boxShadow: `0 0 0 1.5px ${color}` }}
        />
      ) : (
        <span
          aria-hidden="true"
          className="flex h-4 w-4 items-center justify-center rounded-full text-[8px] font-semibold text-white"
          style={{ backgroundColor: color }}
        >
          {initials}
        </span>
      )}
      <span className="max-w-[80px] truncate text-gray-700">{name}</span>
    </span>
  )
}

/** Convert "Alice Cooper" → "AC", single names → "A", empty → "?". */
export function nameToInitials(name: string): string {
  const cleaned = name.trim()
  if (!cleaned) return '?'
  const parts = cleaned.split(/\s+/).slice(0, 2)
  return (
    parts
      .map((p) => (p[0] ?? '').toUpperCase())
      .filter(Boolean)
      .join('') || '?'
  )
}
