import React, { useState, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { useVoiceStore } from '../../stores/voiceStore';
import { useChatStore } from '../../stores/chatStore';
import { useSpaceStore, getChannelOrigin } from '../../stores/spaceStore';
import { getActiveRoom } from '../../hooks/useLiveKit';
import { wsSend } from '../../hooks/useWebSocket';
import { ScreenShareSettingsPopover } from './ScreenShareSettingsPopover';
import { ConnectionInfoPopover } from './ConnectionInfoPopover';
import { SoundboardPopover } from './SoundboardPopover';
import { startScreenShare, stopScreenShare } from '../../utils/screenShare';
import { hasPermissionBit, PermissionBits } from '../../utils/permissions';
import { broadcastVoiceStatus } from '../../utils/voice';
import { handleCameraAction } from '../../utils/voiceActions';

/**
 * VoiceControls renders the voice status + button rows.
 * It has NO wrapper/card styling — the parent provides the container.
 */
export function VoiceControls() {
  const currentVoiceChannelId = useVoiceStore((s) => s.currentVoiceChannelId);
  const currentVoiceSpaceId = useVoiceStore((s) => s.currentVoiceSpaceId);
  const currentVoiceChannelName = useVoiceStore((s) => s.currentVoiceChannelName);
  const setCurrentChannel = useChatStore((s) => s.setCurrentChannel);
  const navigate = useNavigate();
  const [showSoundboard, setShowSoundboard] = useState(false);
  const isCameraOn = useVoiceStore((s) => s.isCameraOn);
  const isScreenSharing = useVoiceStore((s) => s.isScreenSharing);
  const rnnoiseEnabled = useVoiceStore((s) => s.rnnoiseEnabled);
  const setRnnoiseEnabled = useVoiceStore((s) => s.setRnnoiseEnabled);
  const connectionError = useVoiceStore((s) => s.connectionError);
  const isLiveKitConnected = useVoiceStore((s) => s.isLiveKitConnected);
  const connectionQuality = useVoiceStore((s) => s.connectionQuality);
  const channels = useSpaceStore((s) => s.channels);
  const [showScreenShareSettings, setShowScreenShareSettings] = useState(false);
  const [showConnectionInfo, setShowConnectionInfo] = useState(false);
  const connectionBtnRef = useRef<HTMLButtonElement>(null);
  const qualityBtnRef = useRef<HTMLButtonElement>(null);

  const activeDmCall = useVoiceStore((s) => s.activeDmCall);
  const channelPerms = useSpaceStore((s) => currentVoiceChannelId ? s.channelPermissions.get(currentVoiceChannelId) : undefined);
  // MANAGE_SPACE lives in the space-level bitfield, not the per-channel one —
  // reading it from channelPermissions silently yielded false for everyone.
  const spacePerms = useSpaceStore((s) => currentVoiceSpaceId ? s.spacePermissions.get(currentVoiceSpaceId) : undefined);
  const canManageSpace = hasPermissionBit(spacePerms, PermissionBits.MANAGE_SPACE);

  // In DM calls, all permissions are granted; in space channels, check SPEAK and STREAM
  const isDmCall = !!activeDmCall;
  const canSpeak = isDmCall || hasPermissionBit(channelPerms, PermissionBits.SPEAK);
  const canStream = isDmCall || hasPermissionBit(channelPerms, PermissionBits.STREAM);

  const voiceOrigin = currentVoiceChannelId ? getChannelOrigin(currentVoiceChannelId) : '';

  if (!currentVoiceChannelId && !activeDmCall) return null;

  const channel = channels.find(c => c.id === currentVoiceChannelId);
  const channelName =
    channel?.name ?? currentVoiceChannelName ?? (activeDmCall ? 'DM Call' : 'Voice Channel');

  // Jump back to where the call is happening. DM calls live under @me; space
  // calls under the space captured at join time.
  const callSpaceId = activeDmCall ? '@me' : currentVoiceSpaceId;
  const callChannelId = activeDmCall ? activeDmCall.dmChannelId : currentVoiceChannelId;
  const canGoToCall = Boolean(callChannelId && callSpaceId && !connectionError);

  const handleGoToCall = () => {
    if (!canGoToCall || !callChannelId) return;
    setCurrentChannel(callChannelId);
    navigate(`/channels/${callSpaceId}/${callChannelId}`);
  };

  const handleScreenShare = async () => {
    const room = getActiveRoom();
    console.log('[SS] handleScreenShare clicked, room:', !!room, 'isScreenSharing:', isScreenSharing);
    if (!room) return;
    try {
      if (!isScreenSharing) {
        const started = await startScreenShare(room);
        if (started) broadcastVoiceStatus();
      } else {
        await stopScreenShare(room);
        broadcastVoiceStatus();
      }
    } catch (err) {
      console.error('[VoiceControls] Failed to toggle screen share:', err);
    }
  };

  const handleDisconnect = () => {
    const { activeDmCall, disconnectFn, federatedCallId, callOrigin } = useVoiceStore.getState();
    if (activeDmCall) {
      const origin = callOrigin || getChannelOrigin(activeDmCall.dmChannelId);
      wsSend({ type: 'dm_call_end', dmChannelId: activeDmCall.dmChannelId, federatedCallId }, origin);
      useVoiceStore.getState().setActiveDmCall(null);
    } else {
      wsSend({ type: 'voice_leave' }, voiceOrigin);
      useVoiceStore.getState().leaveVoice();
    }
    if (disconnectFn) disconnectFn();
  };

  const statusColor = connectionError
    ? 'text-txt-danger'
    : isLiveKitConnected
      ? 'text-status-online'
      : 'text-status-idle';

  const statusBgColor = connectionError
    ? 'bg-accent-rose/20'
    : isLiveKitConnected
      ? 'bg-status-online/20'
      : 'bg-status-idle/20';

  const qualityColor =
    connectionQuality === 'excellent' || connectionQuality === 'good'
      ? 'text-status-online'
      : connectionQuality === 'poor'
        ? 'text-status-idle'
        : connectionQuality === 'lost'
          ? 'text-txt-danger'
          : statusColor; // 'unknown' falls back to connection-state color

  const btnBase = 'flex-1 h-[34px] flex items-center justify-center rounded-[4px] transition-colors';
  const btnDefaultStyle = 'bg-surface-base text-txt-tertiary hover:bg-surface-channel hover:text-txt-secondary';

  return (
    <>
      {/* Zero-height anchor: the component returns a fragment, so without a
          positioned ancestor the popover would resolve against whatever
          happened to be relative further up the sidebar. */}
      <div className="relative">
        {showSoundboard && currentVoiceSpaceId && (
          <SoundboardPopover
            spaceId={currentVoiceSpaceId}
            canManage={canManageSpace}
            onClose={() => setShowSoundboard(false)}
          />
        )}
      </div>

      {/* Row 1: Signal icon + status text + disconnect */}
      <div className="relative flex items-center gap-2 px-3 pt-3 pb-1">
        <button
          ref={connectionBtnRef}
          onClick={() => {
            setShowConnectionInfo(!showConnectionInfo);
            if (!showConnectionInfo) setShowScreenShareSettings(false);
          }}
          className={`w-8 h-8 rounded-lg ${statusBgColor} flex items-center justify-center flex-shrink-0 hover:brightness-125 transition-all`}
          title="Connection Info"
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" className={qualityColor}>
            <path d="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.08 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z" />
          </svg>
        </button>

        <div className="min-w-0 flex-1">
          <div className={`text-[13px] font-semibold leading-[18px] ${statusColor}`}>
            {connectionError ? 'Connection Failed' : isLiveKitConnected ? 'Voice Connected' : 'Connecting...'}
          </div>
          {canGoToCall ? (
            <button
              onClick={handleGoToCall}
              title="Go to call"
              className="text-[12px] text-txt-tertiary truncate leading-[16px] w-full text-left hover:text-txt-primary hover:underline transition-colors cursor-pointer"
            >
              {channelName}
            </button>
          ) : (
            <div className="text-[12px] text-txt-tertiary truncate leading-[16px]">
              {connectionError ? connectionError : channelName}
            </div>
          )}
        </div>

        <div className="flex items-center gap-0.5 flex-shrink-0">
          <button
            onClick={handleDisconnect}
            className="w-7 h-7 flex items-center justify-center text-txt-tertiary hover:text-txt-primary transition-colors rounded"
            title="Disconnect"
          >
            <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
              <path d="M12 9C10.4 9 8.85 9.25 7.4 9.72V12.82C7.4 13.22 7.17 13.56 6.84 13.72C5.86 14.21 4.97 14.84 4.18 15.57C4 15.75 3.75 15.85 3.48 15.85C3.2 15.85 2.95 15.74 2.77 15.56L0.29 13.08C0.11 12.9 0 12.65 0 12.38C0 12.1 0.11 11.85 0.29 11.67C3.34 8.78 7.46 7 12 7S20.66 8.78 23.71 11.67C23.89 11.85 24 12.1 24 12.38C24 12.65 23.89 12.9 23.71 13.08L21.23 15.56C21.05 15.74 20.8 15.85 20.52 15.85C20.25 15.85 20 15.75 19.82 15.57C19.03 14.84 18.14 14.21 17.16 13.72C16.83 13.56 16.6 13.22 16.6 12.82V9.72C15.15 9.25 13.6 9 12 9Z" />
            </svg>
          </button>
        </div>

        {/* Connection Info Popover */}
        <ConnectionInfoPopover
          open={showConnectionInfo}
          onClose={() => setShowConnectionInfo(false)}
          anchorRef={connectionBtnRef}
        />
      </div>

      {/* Row 2: Camera, Screen Share, Video Quality, Noise Suppression */}
      <div className="relative flex items-center gap-1 px-3 pb-2 pt-1">
        {canSpeak && (
          <button
            onClick={handleCameraAction}
            className={`${btnBase} ${
              isCameraOn
                ? 'bg-surface-base text-status-online hover:bg-surface-channel'
                : btnDefaultStyle
            }`}
            title={isCameraOn ? 'Turn Off Camera' : 'Turn On Camera'}
          >
            {isCameraOn ? (
              <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
                <path d="M17 10.5V7C17 6.45 16.55 6 16 6H4C3.45 6 3 6.45 3 7V17C3 17.55 3.45 18 4 18H16C16.55 18 17 17.55 17 17V13.5L21 17.5V6.5L17 10.5Z" />
              </svg>
            ) : (
              <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
                <path d="M17 10.5V7C17 6.45 16.55 6 16 6H4C3.45 6 3 6.45 3 7V17C3 17.55 3.45 18 4 18H16C16.55 18 17 17.55 17 17V13.5L21 17.5V6.5L17 10.5Z" />
                <line x1="2" y1="2" x2="22" y2="22" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" />
              </svg>
            )}
          </button>
        )}

        {canStream && (
          <button
            onClick={handleScreenShare}
            className={`${btnBase} ${
              isScreenSharing
                ? 'bg-surface-base text-status-online hover:bg-surface-channel'
                : btnDefaultStyle
            }`}
            title={isScreenSharing ? 'Stop Sharing' : 'Share Screen'}
          >
            <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
              <path d="M20 18C21.1 18 22 17.1 22 16V6C22 4.9 21.1 4 20 4H4C2.9 4 2 4.9 2 6V16C2 17.1 2.9 18 4 18H0V20H24V18H20ZM4 6H20V16H4V6Z" />
              <path d="M15 11L11 14V12H9V10H11V8L15 11Z" />
            </svg>
          </button>
        )}

        {/* Soundboard — space calls only: clips belong to a space. */}
        {currentVoiceSpaceId && (
          <button
            onClick={() => setShowSoundboard((v) => !v)}
            className={`${btnBase} ${
              showSoundboard
                ? 'bg-surface-base text-accent-primary hover:bg-surface-channel'
                : btnDefaultStyle
            }`}
            title="Soundboard"
          >
            <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
              <path d="M12 3v10.55A4 4 0 1 0 14 17V7h4V3h-6Z" />
            </svg>
          </button>
        )}

        {/* Video Quality */}
        <button
          ref={qualityBtnRef}
          onClick={() => {
            setShowScreenShareSettings(!showScreenShareSettings);
            if (!showScreenShareSettings) setShowConnectionInfo(false);
          }}
          className={`${btnBase} ${
            showScreenShareSettings
              ? 'bg-surface-base text-accent-primary hover:bg-surface-channel'
              : btnDefaultStyle
          }`}
          title="Video Quality"
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
            <path d="M3 5v14h18V5H3zm16 12H5V7h14v10z" />
            <path d="M8 15l2.5-3.21L13 15l2-2.5L18 17H6z" />
          </svg>
        </button>

        {/* AI Noise Suppression (RNNoise) */}
        <button
          onClick={() => setRnnoiseEnabled(!rnnoiseEnabled)}
          className={`${btnBase} ${
            rnnoiseEnabled
              ? 'bg-surface-base text-status-online hover:bg-surface-channel'
              : btnDefaultStyle
          }`}
          title={rnnoiseEnabled ? 'Disable AI Noise Suppression' : 'Enable AI Noise Suppression'}
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
            <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z" opacity={rnnoiseEnabled ? 0.15 : 0.08} />
            <path d="M12 1a2 2 0 012 2v1a2 2 0 01-4 0V3a2 2 0 012-2z" />
            <path d="M12 7c-1.66 0-3 1.34-3 3v2c0 1.66 1.34 3 3 3s3-1.34 3-3v-2c0-1.66-1.34-3-3-3z" />
            <path d="M17 11v1c0 2.76-2.24 5-5 5s-5-2.24-5-5v-1H5v1c0 3.53 2.61 6.43 6 6.92V21h2v-2.08c3.39-.49 6-3.39 6-6.92v-1h-2z" />
            {rnnoiseEnabled ? (
              <>
                <circle cx="18" cy="5" r="1.2" fill="currentColor" />
                <circle cx="20" cy="8" r="0.9" fill="currentColor" opacity="0.7" />
                <circle cx="6" cy="5" r="1.2" fill="currentColor" />
                <circle cx="4" cy="8" r="0.9" fill="currentColor" opacity="0.7" />
              </>
            ) : (
              <line x1="4" y1="4" x2="20" y2="20" stroke="currentColor" strokeWidth="2" strokeLinecap="round" opacity="0.4" />
            )}
          </svg>
        </button>

        {/* Screen Share Settings Popover */}
        <ScreenShareSettingsPopover
          open={showScreenShareSettings}
          onClose={() => setShowScreenShareSettings(false)}
          anchorRef={qualityBtnRef}
        />
      </div>
    </>
  );
}
