import type { ConversationSummary } from '@chat-app/shared/chat';
import { useTranslation } from 'react-i18next';

import { useAuth } from '../context/AuthContext';
import { useCall } from '../context/CallContext';
import { useCallPresence } from '../lib/useCallPresence';
import { Avatar } from './Avatar';
import { PhoneIcon, SpinnerIcon } from './icons';

interface Props {
  conversation: ConversationSummary;
}

const MAX_AVATARS = 5;

/**
 * Discord-style persistent voice-channel band rendered at the top of the
 * message surface. Always visible for groups so any member can pop in
 * without an invite-ring; for 1:1 conversations only when someone's already
 * in (a soft "rejoin" affordance). Joining uses the existing joinActiveCall
 * path which sends no invite signals.
 */
export function VoiceChannelRail({ conversation }: Props) {
  const { t } = useTranslation(['app']);
  const { session } = useAuth();
  const { state, joinActiveCall } = useCall();
  const presentIds = useCallPresence(conversation.id);

  const myId = session?.user.id ?? null;
  const iAmIn =
    (state.kind === 'connected' ||
      state.kind === 'connecting' ||
      state.kind === 'reconnecting') &&
    state.conversationId === conversation.id;

  const others = presentIds.filter((u) => u !== myId);
  const isGroup = conversation.type === 'group';

  // For groups: persistent channel feel — show even when empty.
  // For DMs: only when somebody is already in (matches Discord-DM behaviour).
  const visible = !iAmIn && (isGroup || others.length > 0);
  if (!visible) return null;

  const showAvatars = others.slice(0, MAX_AVATARS);
  const overflow = Math.max(0, others.length - MAX_AVATARS);
  const busy = state.kind !== 'idle';

  const handleJoin = () => {
    if (busy) return;
    void joinActiveCall(conversation.id, 'audio');
  };

  return (
    <div
      role="button"
      tabIndex={0}
      onClick={handleJoin}
      onKeyDown={(e) => {
        if (e.key === 'Enter' || e.key === ' ') {
          e.preventDefault();
          handleJoin();
        }
      }}
      className={
        'flex cursor-pointer items-center gap-3 border-b border-line px-5 py-2.5 text-sm transition focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/40 ' +
        (others.length > 0
          ? 'bg-emerald-500/10 hover:bg-emerald-500/15'
          : 'bg-surface-3/70 hover:bg-surface-3')
      }
    >
      <div
        className={
          'flex h-8 w-8 shrink-0 items-center justify-center rounded-md ' +
          (others.length > 0 ? 'bg-emerald-500/20 text-emerald-500' : 'bg-accent/15 text-accent')
        }
      >
        <PhoneIcon className="h-4 w-4" />
      </div>
      <div className="min-w-0 flex-1">
        <p className="text-[11px] font-semibold uppercase tracking-[0.12em] text-fg-muted">
          {t('app:call.voice_channel', { defaultValue: 'Sprach-Channel' })}
        </p>
        <p className="truncate text-xs text-fg">
          {others.length === 0
            ? t('app:call.voice_empty', {
                defaultValue: 'Niemand drin — sei der Erste.',
              })
            : t('app:call.voice_count', {
                defaultValue: '{{count}} im Channel',
                count: others.length,
              })}
        </p>
      </div>
      {showAvatars.length > 0 && (
        <div className="flex -space-x-2">
          {showAvatars.map((id) => {
            const member = conversation.members.find((m) => m.userId === id);
            return (
              <div
                key={id}
                title={member?.profile?.displayName ?? '?'}
                className="relative h-7 w-7 overflow-hidden rounded-full border-2 border-surface-3 bg-surface-2"
              >
                <Avatar
                  url={member?.profile?.avatarUrl ?? null}
                  displayName={member?.profile?.displayName ?? '?'}
                  className="h-full w-full text-[10px]"
                />
              </div>
            );
          })}
          {overflow > 0 && (
            <span className="inline-flex h-7 min-w-[1.75rem] items-center justify-center rounded-full border-2 border-surface-3 bg-surface-2 px-1.5 text-[10px] font-semibold text-fg-muted">
              +{overflow}
            </span>
          )}
        </div>
      )}
      <button
        type="button"
        onClick={(e) => {
          e.stopPropagation();
          handleJoin();
        }}
        disabled={busy}
        className="inline-flex shrink-0 cursor-pointer items-center gap-1.5 rounded-md bg-emerald-600 px-3 py-1.5 text-xs font-semibold text-white transition hover:bg-emerald-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-emerald-400/40 disabled:cursor-not-allowed disabled:opacity-60"
      >
        {busy ? (
          <SpinnerIcon className="h-3.5 w-3.5" />
        ) : (
          <PhoneIcon className="h-3.5 w-3.5" />
        )}
        <span>
          {others.length === 0
            ? t('app:call.voice_open', { defaultValue: 'Channel öffnen' })
            : t('app:call.join', { defaultValue: 'Beitreten' })}
        </span>
      </button>
    </div>
  );
}
