'use client'

import React from 'react'

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

/**
 * Compact connection + offline-draft indicator. Rendered alongside the
 * presence chips above the editor toolbar so editors get a single,
 * always-visible signal:
 *
 * - **Saved & synced** — IndexedDB store is ready and the gateway
 *   socket is connected.
 * - **Saved locally** — IndexedDB ready but the socket is disconnected
 *   (offline drafts in flight; will sync on reconnect).
 * - **Syncing local copy…** — IndexedDB is replaying the last snapshot
 *   into the doc. The editor is still usable but undo / cursor sync
 *   may flicker briefly.
 * - **Local drafts unsupported** — `indexedDB` is unavailable; the
 *   editor will rely on the gateway only. Refresh loses uncommitted
 *   edits.
 * - **Local drafts failed** — IndexedDB threw on init (quota, private
 *   browsing). Same risk as "unsupported", but with a different cause.
 *
 * Keeping the component dumb and prop-driven keeps the unit tests
 * trivial — the parent owns the status transitions.
 */
export interface OfflineStatusProps {
  connection: CollaborationStatus
  offline: OfflinePersistenceStatus
}

export function OfflineStatus({ connection, offline }: OfflineStatusProps): React.JSX.Element {
  const { label, tone } = describeOfflineStatus(connection, offline)
  const baseClass = 'inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[11px] font-medium'
  const toneClass = TONE_CLASSES[tone]
  return (
    <span className={`${baseClass} ${toneClass}`} data-testid="offline-status" data-tone={tone}>
      <span
        aria-hidden="true"
        className={`inline-block h-1.5 w-1.5 rounded-full ${DOT_CLASSES[tone]}`}
      />
      {label}
    </span>
  )
}

export type OfflineTone = 'good' | 'warn' | 'info' | 'bad'

const TONE_CLASSES: Record<OfflineTone, string> = {
  good: 'bg-emerald-50 text-emerald-700',
  warn: 'bg-amber-50 text-amber-800',
  info: 'bg-blue-50 text-blue-700',
  bad: 'bg-red-50 text-red-700',
}

const DOT_CLASSES: Record<OfflineTone, string> = {
  good: 'bg-emerald-500',
  warn: 'bg-amber-500',
  info: 'bg-blue-500',
  bad: 'bg-red-500',
}

/**
 * Pure helper that maps the (connection, offline) status pair to a
 * single user-facing label + colour tone. Exported so the unit tests
 * can exercise every combination without rendering React.
 */
export function describeOfflineStatus(
  connection: CollaborationStatus,
  offline: OfflinePersistenceStatus,
): { label: string; tone: OfflineTone } {
  if (offline === 'error') return { label: 'Local drafts failed', tone: 'bad' }
  if (offline === 'unsupported') {
    // No local persistence; the WebSocket is the only safety net.
    if (connection === 'connected') return { label: 'Synced', tone: 'good' }
    if (connection === 'connecting') return { label: 'Connecting…', tone: 'info' }
    return { label: 'Offline — drafts not persisted', tone: 'warn' }
  }
  if (offline === 'loading' || offline === 'pending') {
    return { label: 'Restoring local copy…', tone: 'info' }
  }
  // offline === 'ready' from here on.
  if (connection === 'connected') return { label: 'Saved & synced', tone: 'good' }
  if (connection === 'connecting') return { label: 'Saved locally — reconnecting…', tone: 'warn' }
  return { label: 'Saved locally — offline', tone: 'warn' }
}
