import { useTranslation } from 'react-i18next';

import {
  CaptionsIcon,
  HeadphonesIcon,
  HeadphonesOffIcon,
  MicIcon,
  MicOffIcon,
  MonitorShareIcon,
  MonitorStopIcon,
  MusicIcon,
  PhoneOffIcon,
  UsersIcon,
  VideoIcon,
} from './icons';

interface Props {
  muted: boolean;
  sharing: boolean;
  video: boolean;
  deafened: boolean;
  onToggleMute: () => void;
  onToggleShare: () => void;
  /** Right-click on the share button opens the quality picker dialog while
   *  left-click just starts with last-used settings. Optional so pages that
   *  don't need the advanced path (mobile, etc.) can skip it. */
  onShareContextMenu?: (e: React.MouseEvent) => void;
  onToggleVideo?: () => void;
  onToggleDeafen: () => void;
  onHangup: () => void;
  onOpenParticipants?: () => void;
  /** Toggle the in-call soundboard popover. Active = panel currently open. */
  onToggleSoundboard?: () => void;
  soundboardOpen?: boolean;
  /** Discord-style live-captions toggle. Optional — pages that don't support
   *  SpeechRecognition (Firefox) skip the prop and the button is hidden. */
  onToggleCaptions?: () => void;
  captionsOn?: boolean;
  participantsOpen?: boolean;
  /** Compact variant used inside the docked call (36px buttons). */
  compact?: boolean;
  /** Glass variant used when controls float on fullscreen cinema mode. */
  glass?: boolean;
  /** Disable transient interactions while the call isn't fully connected. */
  disabledMedia?: boolean;
}

export function CallControls({
  muted,
  sharing,
  video,
  deafened,
  onToggleMute,
  onToggleShare,
  onShareContextMenu,
  onToggleVideo,
  onToggleDeafen,
  onHangup,
  onOpenParticipants,
  onToggleSoundboard,
  soundboardOpen = false,
  onToggleCaptions,
  captionsOn = false,
  participantsOpen = false,
  compact = false,
  glass = false,
  disabledMedia = false,
}: Props) {
  const { t } = useTranslation(['app']);
  const wrapBase = glass
    ? 'glass-pill flex items-center justify-center gap-2 rounded-[18px] p-2.5'
    : 'flex items-center justify-center gap-2 border-t border-line bg-surface-3 p-3';
  const btnSize = compact ? 'h-9 w-9 rounded-[10px]' : 'h-12 w-12 rounded-[14px]';
  const hangupSize = compact ? 'h-9 w-[54px] rounded-[10px]' : 'h-12 w-[72px] rounded-[14px]';
  return (
    <div className={wrapBase}>
      <CallButton
        label={muted ? t('app:call.unmute') : t('app:call.mute')}
        active={muted}
        activeTone="danger"
        onClick={onToggleMute}
        disabled={disabledMedia}
        glass={glass}
        className={btnSize}
      >
        {muted ? <MicOffIcon className="h-5 w-5" /> : <MicIcon className="h-5 w-5" />}
      </CallButton>
      <CallButton
        label={
          deafened
            ? t('app:call.undeafen', { defaultValue: 'Ton wieder aktiv' })
            : t('app:call.deafen', { defaultValue: 'Alle stumm' })
        }
        active={deafened}
        activeTone="danger"
        onClick={onToggleDeafen}
        glass={glass}
        className={btnSize}
      >
        {deafened ? (
          <HeadphonesOffIcon className="h-5 w-5" />
        ) : (
          <HeadphonesIcon className="h-5 w-5" />
        )}
      </CallButton>
      {onToggleVideo && (
        <CallButton
          label={t('app:call.start_video', { defaultValue: 'Video' })}
          active={video}
          activeTone="accent"
          onClick={onToggleVideo}
          disabled={disabledMedia}
          glass={glass}
          className={btnSize}
        >
          <VideoIcon className="h-5 w-5" />
        </CallButton>
      )}
      <CallButton
        label={
          sharing
            ? t('app:call.stop_share_screen', { defaultValue: 'Screen-Share stoppen' })
            : t('app:call.share_screen', { defaultValue: 'Bildschirm teilen' })
        }
        active={sharing}
        activeTone="accent"
        onClick={onToggleShare}
        {...(onShareContextMenu ? { onContextMenu: onShareContextMenu } : {})}
        disabled={disabledMedia}
        glass={glass}
        className={btnSize}
      >
        {sharing ? (
          <MonitorStopIcon className="h-5 w-5" />
        ) : (
          <MonitorShareIcon className="h-5 w-5" />
        )}
      </CallButton>
      {onToggleSoundboard && (
        <CallButton
          label={t('app:soundboard.toggle', { defaultValue: 'Soundboard' })}
          active={soundboardOpen}
          activeTone="accent"
          onClick={onToggleSoundboard}
          glass={glass}
          className={btnSize}
        >
          <MusicIcon className="h-5 w-5" />
        </CallButton>
      )}
      {onToggleCaptions && (
        <CallButton
          label={
            captionsOn
              ? t('app:call.captions_off', { defaultValue: 'Untertitel aus' })
              : t('app:call.captions_on', { defaultValue: 'Untertitel an' })
          }
          active={captionsOn}
          activeTone="accent"
          onClick={onToggleCaptions}
          glass={glass}
          className={btnSize}
        >
          <CaptionsIcon className="h-5 w-5" />
        </CallButton>
      )}
      {onOpenParticipants && (
        <CallButton
          label={t('app:call.participants', { defaultValue: 'Teilnehmer' })}
          onClick={onOpenParticipants}
          active={participantsOpen}
          activeTone="accent"
          dataTrigger="participants"
          glass={glass}
          className={btnSize}
        >
          <UsersIcon className="h-5 w-5" />
        </CallButton>
      )}
      <CallButton
        label={t('app:call.hangup')}
        onClick={onHangup}
        tone="danger"
        glass={glass}
        className={hangupSize}
      >
        <PhoneOffIcon className="h-5 w-5" />
      </CallButton>
    </div>
  );
}

interface CallButtonProps {
  label: string;
  onClick: () => void;
  onContextMenu?: (e: React.MouseEvent) => void;
  disabled?: boolean;
  active?: boolean;
  activeTone?: 'accent' | 'danger';
  tone?: 'default' | 'danger';
  glass?: boolean;
  className?: string;
  /** Stable trigger id so portals (popovers) can skip outside-click dismiss
   *  when the user is toggling their own trigger. */
  dataTrigger?: string;
  children: React.ReactNode;
}

function CallButton({
  label,
  onClick,
  onContextMenu,
  disabled,
  active,
  activeTone = 'accent',
  tone = 'default',
  glass = false,
  className = '',
  dataTrigger,
  children,
}: CallButtonProps) {
  const base =
    'inline-flex cursor-pointer items-center justify-center border transition focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/50 disabled:cursor-not-allowed disabled:opacity-50';

  let toneClass: string;
  if (tone === 'danger') {
    toneClass = 'bg-rose-600 text-white border-rose-600 hover:bg-rose-500';
  } else if (active && activeTone === 'danger') {
    toneClass = 'bg-rose-600 text-white border-rose-600 hover:bg-rose-500';
  } else if (active) {
    toneClass = 'bg-accent text-accent-fg border-accent hover:brightness-110';
  } else if (glass) {
    toneClass =
      'border-white/15 bg-white/10 text-white hover:bg-white/15';
  } else {
    toneClass = 'border-line bg-surface-2 text-fg hover:bg-surface';
  }

  return (
    <button
      type="button"
      onClick={onClick}
      onContextMenu={onContextMenu}
      disabled={disabled}
      aria-label={label}
      aria-pressed={active}
      title={label}
      className={`${base} ${toneClass} ${className}`}
      {...(dataTrigger ? { [`data-${dataTrigger}-trigger`]: 'true' } : {})}
    >
      {children}
    </button>
  );
}
