import { useEffect, useRef, useState, useCallback, useMemo } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'
import { buildCustoms, waitForIceGathering, PARTICIPANTS, RECORDING_CONFIG, WEBHOOK_URL, VX_SERVER } from '../lib/webrtc'
import { decodeSessionConfig } from '../lib/sessionConfig'
import { COMPANIES } from '../lib/companies'

const DEFAULT_KEY    = import.meta.env.VITE_FLOW_API_KEY || ''

export default function Room({ sessionId, state }) {
  const navigate = useNavigate()
  const location = useLocation()

  // Config resolution: state (dev shortcut) OR URL ?cfg= param (normal interviewee flow)
  const config = useMemo(() => {
    if (state?.name || state?.candidateName) return state
    const encoded = new URLSearchParams(location.search).get('cfg')
    return encoded ? decodeSessionConfig(encoded) : null
  }, [state, location.search])

  const name          = config?.candidateName || config?.name || ''
  const companyId     = typeof config?.company === 'string' ? config.company : config?.company?.id
  const companyObj    = companyId ? (COMPANIES[companyId] || config?.company) : config?.company
  const apiKey        = config?.apiKey  || DEFAULT_KEY
  const server        = config?.server  || VX_SERVER
  const voiceSettings = config?.voiceSettings || null

  // Interviewee opened via URL → show join screen before connecting
  const isUrlFlow = !state?.name && !state?.candidateName
  const [started, setStarted] = useState(!isUrlFlow)

  const watchUrl = `${window.location.origin}${window.location.pathname}#/watch/${sessionId}`

  const pcRef        = useRef(null)
  const streamRef    = useRef(null)
  const audioCtxRef  = useRef(null)
  const userVideoRef = useRef(null)
  const aiVideoRef   = useRef(null)
  const aiAudioRef   = useRef(null)
  const chatEndRef   = useRef(null)

  const [connState,    setConnState]    = useState('connecting')
  const [aiState,      setAiState]      = useState('waiting')
  const [userSpeaking, setUserSpeaking] = useState(false)
  const [aiSpeaking,   setAiSpeaking]   = useState(false)
  const [micMuted,     setMicMuted]     = useState(false)
  const [hasUserVid,   setHasUserVid]   = useState(false)
  const [hasAiVid,     setHasAiVid]     = useState(false)
  const [elapsed,      setElapsed]      = useState(0)
  const [chatMessages, setChatMessages] = useState([])
  const [copied,       setCopied]       = useState(false)

  // Timer — only runs once started
  useEffect(() => {
    if (!started) return
    const t = setInterval(() => setElapsed(s => s + 1), 1000)
    return () => clearInterval(t)
  }, [started])

  useEffect(() => {
    chatEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [chatMessages])

  // SSE — subscribe once we have a session
  useEffect(() => {
    if (!started) return
    const es = new EventSource(`${WEBHOOK_URL}/events?session=${sessionId}`)

    es.onmessage = e => {
      try {
        const data = JSON.parse(e.data)
        const responses = data.responses || []
        const msgs = []

        // User transcript — non-streaming entry with out.user_input
        const userEntry = responses.find(r => !r.streaming && r.out?.user_input)
        if (userEntry) {
          const text = userEntry.out.user_input
            .replace(/<turn-visual-context>[\s\S]*?<\/turn-visual-context>/g, '')
            .replace(/<non-verbal-elements>[\s\S]*?<\/non-verbal-elements>/g, '')
            .trim()
          if (text) msgs.push({ role: 'user', text })
        }

        // AI text — main LLM only (prev_llm is audio filler, not transcript)
        const aiRaw = responses
          .filter(r => r.streaming && r.chunk && r.node === 'llm')
          .map(r => r.chunk)
          .join('')
        const aiText = aiRaw
          .split(/<\|speak\|>/)
          .map(seg => seg.replace(/<\|hangup\|>\S*/g, '').trim())
          .filter(Boolean)
          .join(' ')
          .trim()
        if (aiText) msgs.push({ role: 'ai', text: aiText })

        if (msgs.length) setChatMessages(prev => [...prev, ...msgs])
      } catch {}
    }

    return () => es.close()
  }, [sessionId, started])

  // VAD
  const startVAD = useCallback((analyser, threshold, onSpeak, onSilence) => {
    const buf = new Uint8Array(analyser.fftSize)
    let speakFrames = 0, silentFrames = 0
    const tick = () => {
      analyser.getByteTimeDomainData(buf)
      let sum = 0
      for (let i = 0; i < buf.length; i++) { const v = (buf[i] - 128) / 128; sum += v * v }
      const rms = Math.sqrt(sum / buf.length) * 100
      if (rms > threshold) {
        speakFrames++; silentFrames = 0
        if (speakFrames > 3) onSpeak()
      } else {
        silentFrames++; speakFrames = 0
        if (silentFrames > 8) onSilence()
      }
      requestAnimationFrame(tick)
    }
    tick()
  }, [])

  const setupUserVAD = useCallback((stream) => {
    const ctx = audioCtxRef.current
    const src = ctx.createMediaStreamSource(stream)
    const an  = ctx.createAnalyser(); an.fftSize = 512; an.smoothingTimeConstant = 0.7
    src.connect(an)
    startVAD(an, 12, () => setUserSpeaking(true), () => setUserSpeaking(false))
  }, [startVAD])

  const setupAIVAD = useCallback((stream) => {
    if (!audioCtxRef.current) audioCtxRef.current = new (window.AudioContext || window.webkitAudioContext)()
    const ctx = audioCtxRef.current
    const src = ctx.createMediaStreamSource(stream)
    const an  = ctx.createAnalyser(); an.fftSize = 512; an.smoothingTimeConstant = 0.7
    src.connect(an)
    startVAD(an, 10,
      () => { setAiSpeaking(true);  setAiState('speaking')  },
      () => { setAiSpeaking(false); setAiState('listening') }
    )
  }, [startVAD])

  // WebRTC bootstrap — only runs when started
  useEffect(() => {
    if (!started || !name || !companyObj) return

    let cancelled         = false
    let reconnectAttempts = 0
    let reconnectTimer    = null
    const MAX_RECONNECTS  = 5

    async function connect(stream) {
      if (cancelled) return

      let iceServers = []
      try {
        const r = await fetch(`${server}/rtc/ice-servers`, { signal: AbortSignal.timeout(3000) })
        if (r.ok) { const d = await r.json(); iceServers = d.ice_servers || [] }
      } catch {}

      const pc = new RTCPeerConnection({ iceServers })
      pcRef.current = pc
      stream.getTracks().forEach(t => pc.addTrack(t, stream))

      pc.ontrack = e => {
        if (e.track.kind === 'audio') {
          aiAudioRef.current.srcObject = e.streams[0]
          setupAIVAD(e.streams[0])
        } else if (e.track.kind === 'video') {
          aiVideoRef.current.srcObject = e.streams[0]
          setHasAiVid(true)
        }
      }

      pc.onconnectionstatechange = () => {
        const st = pc.connectionState
        if (st === 'connected') { reconnectAttempts = 0; setConnState('connected') }
        if (st === 'failed' || st === 'disconnected') {
          pc.close()
          if (!cancelled && reconnectAttempts < MAX_RECONNECTS) {
            reconnectAttempts++
            setConnState('connecting')
            reconnectTimer = setTimeout(() => connect(stream), Math.min(1000 * reconnectAttempts, 5000))
          } else if (!cancelled) {
            setConnState('failed')
          }
        }
      }

      const offer = await pc.createOffer()
      await pc.setLocalDescription(offer)
      await waitForIceGathering(pc)

      const customs = buildCustoms(companyId, name, voiceSettings)

      let resp
      try {
        resp = await fetch(`${server}/rtc/offer/audio`, {
          method:  'POST',
          headers: { 'Content-Type': 'application/json', 'api_key': apiKey },
          body:    JSON.stringify({
            sdp:          pc.localDescription.sdp,
            type:         pc.localDescription.type,
            participants: PARTICIPANTS,
            customs,
            session_id:   sessionId,
            ...RECORDING_CONFIG,
          }),
        })
      } catch {
        if (!cancelled && reconnectAttempts < MAX_RECONNECTS) {
          reconnectAttempts++
          setConnState('connecting')
          reconnectTimer = setTimeout(() => connect(stream), Math.min(1000 * reconnectAttempts, 5000))
        } else {
          setConnState('failed')
        }
        return
      }

      if (!resp.ok) { setConnState('failed'); return }
      const answer = await resp.json()
      await pc.setRemoteDescription(new RTCSessionDescription(answer))
    }

    async function start() {
      let stream
      try {
        stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true })
      } catch {
        try { stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false }) }
        catch { setConnState('failed'); return }
      }
      if (cancelled) { stream.getTracks().forEach(t => t.stop()); return }
      streamRef.current = stream

      if (stream.getVideoTracks().length) {
        userVideoRef.current.srcObject = stream
        setHasUserVid(true)
      }

      audioCtxRef.current = new (window.AudioContext || window.webkitAudioContext)()
      setupUserVAD(stream)
      connect(stream)
    }

    start()

    return () => {
      cancelled = true
      clearTimeout(reconnectTimer)
      cleanup()
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [started])

  function cleanup() {
    streamRef.current?.getTracks().forEach(t => t.stop())
    pcRef.current?.close()
    pcRef.current = null
    audioCtxRef.current?.close()
    audioCtxRef.current = null
  }

  function toggleMic() {
    if (!streamRef.current) return
    const next = !micMuted
    setMicMuted(next)
    streamRef.current.getAudioTracks().forEach(t => { t.enabled = !next })
    if (next) setUserSpeaking(false)
  }

  function leave() {
    cleanup()
    navigate('/')
  }

  function copyLink() {
    navigator.clipboard.writeText(watchUrl).then(() => {
      setCopied(true)
      setTimeout(() => setCopied(false), 2000)
    })
  }

  const fmtTime = s => {
    const m  = Math.floor(s / 60).toString().padStart(2, '0')
    const ss = (s % 60).toString().padStart(2, '0')
    return `${m}:${ss}`
  }

  // ── Invalid link ─────────────────────────────────────────────────────────────
  if (!config || !companyObj || !name) {
    return (
      <div style={j.page}>
        <div style={j.inner}>
          <p style={j.errorTitle}>Invalid interview link.</p>
          <button style={j.backBtn} onClick={() => navigate('/')}>← home</button>
        </div>
      </div>
    )
  }

  // ── Interviewee join screen ───────────────────────────────────────────────────
  if (!started) {
    return (
      <div style={j.page}>
        <div style={{ ...j.glow, background: `radial-gradient(ellipse 60% 50% at 30% 50%, ${companyObj.accent}08 0%, transparent 70%)` }} />
        <div style={j.inner}>
          <div style={{ ...j.iconBox, background: `${companyObj.accent}18`, color: companyObj.accent }}>
            {companyObj.icon}
          </div>

          <p style={{ ...j.pill, borderColor: `${companyObj.accent}30`, color: companyObj.accent }}>
            Mock interview
          </p>

          <h1 style={j.title}>
            Ready when<br />
            <span style={{ color: companyObj.accent }}>you are.</span>
          </h1>

          <div style={j.metaRow}>
            <div style={j.metaItem}>
              <span style={j.metaLabel}>Company</span>
              <span style={j.metaValue}>{companyObj.name}</span>
            </div>
            <div style={j.metaDivider} />
            <div style={j.metaItem}>
              <span style={j.metaLabel}>Candidate</span>
              <span style={j.metaValue}>{name}</span>
            </div>
          </div>

          <p style={j.hint}>
            The AI interviewer will open the session. This is a practice run — speak naturally and take your time.
            Your microphone and camera will be requested.
          </p>

          <button
            style={{ ...j.beginBtn, background: companyObj.accent }}
            onClick={() => setStarted(true)}
          >
            Begin interview →
          </button>

          <p style={j.fine}>Everything stays within this session.</p>
        </div>
      </div>
    )
  }

  // ── Interview room ────────────────────────────────────────────────────────────
  const statusLabel  = { connecting: 'Connecting…', connected: 'Connected', failed: 'Connection lost' }
  const aiStateLabel = { waiting: 'Waiting', listening: 'Listening', thinking: 'Thinking…', speaking: 'Speaking' }

  return (
    <div style={s.root}>
      {/* topbar */}
      <header style={s.topbar}>
        <div style={s.topLeft}>
          <span style={s.sessionLabel}>Mock Interview</span>
          <span style={{ ...s.companyChip, color: companyObj.accent, borderColor: `${companyObj.accent}40` }}>
            {companyObj.name}
          </span>
        </div>
        <div style={s.topRight}>
          <span style={s.timer}>{fmtTime(elapsed)}</span>
          <span style={{ ...s.connBadge, ...(connState === 'connected' ? s.connGreen : connState === 'failed' ? s.connRed : s.connYellow) }}>
            {connState}
          </span>
        </div>
      </header>

      {/* body: stage + chat */}
      <div style={s.body}>

        {/* stage */}
        <main style={s.stage}>
          <div style={s.stageGlow1} />
          <div style={s.stageGlow2} />

          {/* user card */}
          <div style={s.participantCol}>
            <div style={{ ...s.avatarWrap, ...(hasUserVid ? s.videoWrap : {}) }}>
              {userSpeaking && !micMuted && !hasUserVid && (
                <>
                  <div style={{ ...s.ring, borderColor: 'var(--user-ring)', animation: 'pulse-ring 1.4s ease-out infinite' }} />
                  <div style={{ ...s.ringOuter, borderColor: 'var(--user-ring)', animation: 'pulse-ring 1.4s ease-out .35s infinite', opacity: .4 }} />
                </>
              )}
              <div style={{ ...s.avatar, ...(hasUserVid ? s.videoAvatar : {}), borderColor: userSpeaking && !micMuted ? 'var(--user-ring)' : 'var(--border2)' }}>
                <video ref={userVideoRef} autoPlay playsInline muted style={{ ...s.selfVideo, display: hasUserVid ? 'block' : 'none' }} />
                {!hasUserVid && (userSpeaking && !micMuted
                  ? <MicBars color="var(--user-ring)" />
                  : <span style={s.avatarIcon}>👤</span>
                )}
              </div>
            </div>
            <span style={s.participantName}>{name}</span>
            <span style={s.participantRole}>candidate</span>
          </div>

          <div style={s.divider} />

          {/* AI card */}
          <div style={s.participantCol}>
            <div style={{ ...s.avatarWrap, ...(hasAiVid ? s.videoWrap : {}) }}>
              {aiSpeaking && !hasAiVid && (
                <>
                  <div style={{ ...s.ring, borderColor: 'var(--ai-ring)', animation: 'pulse-ring 1.4s ease-out infinite' }} />
                  <div style={{ ...s.ringOuter, borderColor: 'var(--ai-ring)', animation: 'pulse-ring 1.4s ease-out .35s infinite', opacity: .4 }} />
                </>
              )}
              <div style={{ ...s.avatar, ...(hasAiVid ? s.videoAvatar : {}), borderColor: aiSpeaking ? 'var(--ai-ring)' : 'var(--border2)' }}>
                <video ref={aiVideoRef} autoPlay playsInline muted style={{ ...s.aiVideo, display: hasAiVid ? 'block' : 'none' }} />
                {!hasAiVid && (aiSpeaking
                  ? <WaveBars color="var(--ai-ring)" />
                  : <span style={s.avatarIcon}>◈</span>
                )}
              </div>
            </div>
            <span style={s.participantName}>{companyObj.name} Interviewer</span>
            <span style={s.participantRole}>AI</span>
          </div>
        </main>

        {/* live chat panel */}
        <aside style={s.chatPanel}>
          <div style={s.observerBar}>
            <div style={s.observerBarLeft}>
              <span style={s.observerLabel}>Observer link</span>
              <span style={s.observerUrl}>{watchUrl}</span>
            </div>
            <button
              style={{ ...s.copyBtn, ...(copied ? s.copyBtnDone : {}) }}
              onClick={copyLink}
            >
              {copied ? 'Copied!' : 'Copy'}
            </button>
          </div>

          <div style={s.chatHeader}>
            <span style={s.chatHeaderLabel}>Live Transcript</span>
            {chatMessages.length > 0 && (
              <span style={s.chatCount}>{chatMessages.length}</span>
            )}
          </div>
          <div style={s.chatScroll}>
            {chatMessages.length === 0
              ? <p style={s.chatEmpty}>Conversation will appear here…</p>
              : chatMessages.map((msg, i) => (
                  <div key={i} style={{ ...s.chatMsg, ...(msg.role === 'user' ? s.chatMsgUser : s.chatMsgAi) }}>
                    <span style={{ ...s.chatRole, color: msg.role === 'user' ? 'var(--user-ring)' : 'var(--ai-ring)' }}>
                      {msg.role === 'user' ? name : 'Interviewer'}
                    </span>
                    <div style={{ ...s.chatBubble, ...(msg.role === 'user' ? s.chatBubbleUser : s.chatBubbleAi) }}>
                      {msg.text}
                    </div>
                  </div>
                ))
            }
            <div ref={chatEndRef} />
          </div>
        </aside>
      </div>

      {/* status row */}
      <div style={s.statusRow}>
        <div style={{ ...s.dot, background: connState === 'connected' ? 'var(--accent)' : connState === 'failed' ? 'var(--danger)' : '#f0c060', animation: connState === 'connecting' ? 'blink .8s step-end infinite' : 'none' }} />
        <span style={s.statusText}>{statusLabel[connState]}</span>
      </div>

      {/* controls */}
      <footer style={s.controls}>
        <button style={{ ...s.ctrlBtn, ...(micMuted ? s.ctrlMuted : {}) }} onClick={toggleMic} title={micMuted ? 'Unmute' : 'Mute'}>
          {micMuted ? <MicOffIcon /> : <MicIcon />}
        </button>

        <div style={{ ...s.aiChip, ...(aiState === 'speaking' ? s.aiChipSpeak : aiState === 'thinking' ? s.aiChipThink : aiState === 'listening' ? s.aiChipListen : {}) }}>
          <div style={{ ...s.aiChipDot, background: aiState === 'speaking' ? 'var(--ai-ring)' : aiState === 'thinking' ? '#f0c060' : aiState === 'listening' ? 'var(--accent)' : 'var(--muted)', animation: aiState === 'thinking' ? 'blink .5s step-end infinite' : 'none' }} />
          <span>{aiStateLabel[aiState]}</span>
        </div>

        <button style={{ ...s.ctrlBtn, ...s.ctrlLeave }} onClick={leave} title="Leave">
          <LeaveIcon />
        </button>
      </footer>

      <audio ref={aiAudioRef} autoPlay />
    </div>
  )
}

// ── Sub-components ────────────────────────────────────────────────────────────

function WaveBars({ color }) {
  const heights = [14, 28, 20, 34, 18]
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 3, height: 36 }}>
      {heights.map((h, i) => (
        <div key={i} style={{ width: 4, minHeight: 4, borderRadius: 2, background: color, animation: `wave-bounce 0.8s ease-in-out ${i * 0.1}s infinite`, '--h': `${h}px` }} />
      ))}
    </div>
  )
}

function MicBars({ color }) {
  const heights = [12, 26, 18, 30, 14]
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 3, height: 36 }}>
      {heights.map((h, i) => (
        <div key={i} style={{ width: 4, minHeight: 4, borderRadius: 2, background: color, animation: `wave-bounce 0.6s ease-in-out ${i * 0.08}s infinite`, '--h': `${h}px` }} />
      ))}
    </div>
  )
}

function MicIcon() {
  return (
    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 2a3 3 0 0 1 3 3v7a3 3 0 0 1-6 0V5a3 3 0 0 1 3-3z"/>
      <path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
      <line x1="12" y1="19" x2="12" y2="22"/>
      <line x1="8" y1="22" x2="16" y2="22"/>
    </svg>
  )
}

function MicOffIcon() {
  return (
    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <line x1="1" y1="1" x2="23" y2="23"/>
      <path d="M9 9v3a3 3 0 0 0 5.12 2.12"/>
      <path d="M15 9.34V5a3 3 0 0 0-5.94-.6"/>
      <path d="M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23"/>
      <line x1="12" y1="19" x2="12" y2="22"/>
      <line x1="8" y1="22" x2="16" y2="22"/>
    </svg>
  )
}

function LeaveIcon() {
  return (
    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
      <polyline points="16 17 21 12 16 7"/>
      <line x1="21" y1="12" x2="9" y2="12"/>
    </svg>
  )
}

// ── Styles ────────────────────────────────────────────────────────────────────

// Join screen styles
const j = {
  page: {
    minHeight: '100vh',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    padding: '48px 20px',
    position: 'relative',
    overflow: 'hidden',
  },
  glow: { position: 'fixed', inset: 0, pointerEvents: 'none' },
  inner: {
    width: '100%',
    maxWidth: 420,
    display: 'flex',
    flexDirection: 'column',
    position: 'relative',
    zIndex: 1,
  },
  iconBox: {
    width: 56,
    height: 56,
    borderRadius: 14,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    fontSize: 24,
    marginBottom: 20,
  },
  pill: {
    display: 'inline-block',
    alignSelf: 'flex-start',
    fontFamily: 'var(--mono)',
    fontSize: 9,
    letterSpacing: '.2em',
    textTransform: 'uppercase',
    border: '1px solid',
    padding: '4px 10px',
    borderRadius: 20,
    marginBottom: 20,
  },
  title: {
    fontSize: 'clamp(32px, 6vw, 50px)',
    fontWeight: 800,
    lineHeight: .95,
    letterSpacing: '-.03em',
    marginBottom: 28,
  },
  metaRow: {
    display: 'flex',
    alignItems: 'stretch',
    gap: 0,
    background: 'var(--surface)',
    border: '1px solid var(--border2)',
    borderRadius: 10,
    overflow: 'hidden',
    marginBottom: 28,
  },
  metaItem: {
    display: 'flex',
    flexDirection: 'column',
    gap: 4,
    padding: '14px 18px',
    flex: 1,
  },
  metaDivider: {
    width: 1,
    background: 'var(--border2)',
    flexShrink: 0,
  },
  metaLabel: {
    fontFamily: 'var(--mono)',
    fontSize: 8,
    letterSpacing: '.2em',
    textTransform: 'uppercase',
    color: 'var(--muted)',
  },
  metaValue: {
    fontFamily: 'var(--sans)',
    fontSize: 14,
    fontWeight: 700,
    color: 'var(--text)',
  },
  hint: {
    fontFamily: 'var(--mono)',
    fontSize: 11,
    color: 'var(--muted)',
    lineHeight: 1.7,
    letterSpacing: '.04em',
    marginBottom: 32,
  },
  beginBtn: {
    color: '#0a0a0a',
    border: 'none',
    fontFamily: 'var(--sans)',
    fontSize: 15,
    fontWeight: 700,
    letterSpacing: '.06em',
    padding: '18px 28px',
    borderRadius: 8,
    cursor: 'pointer',
    marginBottom: 16,
  },
  fine: {
    fontFamily: 'var(--mono)',
    fontSize: 10,
    color: 'var(--muted)',
    letterSpacing: '.1em',
    textAlign: 'center',
  },
  errorTitle: {
    fontFamily: 'var(--mono)',
    fontSize: 13,
    color: 'var(--muted)',
    marginBottom: 16,
  },
  backBtn: {
    fontFamily: 'var(--mono)',
    fontSize: 11,
    color: 'var(--muted)',
    background: 'none',
    border: 'none',
    cursor: 'pointer',
    letterSpacing: '.08em',
    padding: 0,
  },
}

// Room styles
const s = {
  root: { height: '100vh', display: 'flex', flexDirection: 'column', overflow: 'hidden' },
  topbar: {
    display: 'flex', alignItems: 'center', justifyContent: 'space-between',
    padding: '0 28px', height: 56, borderBottom: '1px solid var(--border)', flexShrink: 0,
  },
  topLeft: { display: 'flex', alignItems: 'center', gap: 12 },
  topRight: { display: 'flex', alignItems: 'center', gap: 12 },
  sessionLabel: { fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '.18em', color: 'var(--muted)', textTransform: 'uppercase' },
  companyChip: { fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '.14em', textTransform: 'uppercase', padding: '3px 9px', borderRadius: 20, border: '1px solid' },
  timer: { fontFamily: 'var(--mono)', fontSize: 12, color: 'var(--muted)', letterSpacing: '.1em' },
  connBadge: { fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '.12em', textTransform: 'uppercase', padding: '3px 9px', borderRadius: 20, border: '1px solid var(--border2)', color: 'var(--muted)' },
  connGreen: { color: 'var(--accent)', borderColor: 'var(--accent)' },
  connRed:   { color: 'var(--danger)', borderColor: 'var(--danger)' },
  connYellow:{ color: '#f0c060',        borderColor: '#f0c06040' },

  body: { flex: 1, display: 'flex', overflow: 'hidden' },

  stage: {
    flex: 1,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 48,
    position: 'relative',
    overflow: 'hidden',
  },
  stageGlow1: { position: 'absolute', inset: 0, background: 'radial-gradient(ellipse 50% 40% at 30% 60%, rgba(200,240,96,.04) 0%, transparent 70%)', pointerEvents: 'none' },
  stageGlow2: { position: 'absolute', inset: 0, background: 'radial-gradient(ellipse 40% 40% at 70% 40%, rgba(96,160,240,.03) 0%, transparent 70%)', pointerEvents: 'none' },

  participantCol: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12, position: 'relative', zIndex: 1 },
  avatarWrap: { position: 'relative', width: 120, height: 120 },
  videoWrap:  { width: 160, height: 120 },
  ring: { position: 'absolute', inset: -8, borderRadius: '50%', border: '2px solid', opacity: .6 },
  ringOuter: { position: 'absolute', inset: -16, borderRadius: '50%', border: '1px solid' },
  avatar: {
    width: '100%', height: '100%',
    borderRadius: '50%',
    border: '2px solid',
    background: 'var(--surface)',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    overflow: 'hidden',
    transition: 'border-color .2s',
  },
  videoAvatar: { borderRadius: 12 },
  avatarIcon: { fontSize: 32 },
  selfVideo: { width: '100%', height: '100%', objectFit: 'cover' },
  aiVideo:   { width: '100%', height: '100%', objectFit: 'cover' },
  participantName: { fontFamily: 'var(--sans)', fontSize: 13, fontWeight: 600, color: 'var(--text)' },
  participantRole: { fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '.2em', textTransform: 'uppercase', color: 'var(--muted)' },
  divider: { width: 1, height: 80, background: 'var(--border)' },

  chatPanel: {
    width: 300,
    flexShrink: 0,
    borderLeft: '1px solid var(--border)',
    display: 'flex',
    flexDirection: 'column',
    overflow: 'hidden',
    background: 'var(--surface)',
  },
  observerBar: {
    display: 'flex', alignItems: 'center', justifyContent: 'space-between',
    padding: '10px 14px',
    borderBottom: '1px solid var(--border)',
    gap: 8,
    flexShrink: 0,
  },
  observerBarLeft: { display: 'flex', flexDirection: 'column', gap: 2, flex: 1, minWidth: 0 },
  observerLabel: { fontFamily: 'var(--mono)', fontSize: 8, letterSpacing: '.18em', textTransform: 'uppercase', color: 'var(--muted)' },
  observerUrl: { fontFamily: 'var(--mono)', fontSize: 9, color: 'var(--muted)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },
  copyBtn: { fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '.1em', padding: '4px 10px', borderRadius: 5, border: '1px solid var(--border2)', background: 'transparent', color: 'var(--text)', cursor: 'pointer', flexShrink: 0, transition: 'border-color .15s, color .15s' },
  copyBtnDone: { color: 'var(--accent)', borderColor: 'var(--accent)' },
  chatHeader: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '10px 14px', borderBottom: '1px solid var(--border)', flexShrink: 0 },
  chatHeaderLabel: { fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '.18em', textTransform: 'uppercase', color: 'var(--muted)' },
  chatCount: { fontFamily: 'var(--mono)', fontSize: 9, color: 'var(--muted)', background: 'var(--border2)', padding: '1px 7px', borderRadius: 10 },
  chatScroll: { flex: 1, overflowY: 'auto', padding: '14px', display: 'flex', flexDirection: 'column', gap: 12 },
  chatEmpty: { fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--muted)', letterSpacing: '.08em', textAlign: 'center', paddingTop: 24 },
  chatMsg: { display: 'flex', flexDirection: 'column', gap: 4 },
  chatMsgUser: { alignItems: 'flex-end' },
  chatMsgAi:   { alignItems: 'flex-start' },
  chatRole: { fontFamily: 'var(--mono)', fontSize: 8, letterSpacing: '.18em', textTransform: 'uppercase' },
  chatBubble: { fontSize: 12, lineHeight: 1.6, padding: '8px 11px', borderRadius: 10, wordBreak: 'break-word', maxWidth: '90%' },
  chatBubbleUser: { background: 'rgba(200,240,96,.07)', border: '1px solid rgba(200,240,96,.15)', color: 'var(--text)', borderBottomRightRadius: 3 },
  chatBubbleAi:   { background: 'var(--bg)', border: '1px solid var(--border2)', color: 'var(--text)', borderBottomLeftRadius: 3 },

  statusRow: { display: 'flex', alignItems: 'center', gap: 8, padding: '6px 28px', borderTop: '1px solid var(--border)', flexShrink: 0, background: 'var(--surface)' },
  dot: { width: 6, height: 6, borderRadius: '50%', flexShrink: 0 },
  statusText: { fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '.1em', color: 'var(--muted)' },

  controls: {
    display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 20,
    padding: '14px 28px', borderTop: '1px solid var(--border)', flexShrink: 0,
  },
  ctrlBtn: { width: 44, height: 44, borderRadius: '50%', border: '1px solid var(--border2)', background: 'var(--surface)', color: 'var(--text)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', transition: 'border-color .15s, background .15s' },
  ctrlMuted: { background: 'var(--danger)', borderColor: 'var(--danger)', color: '#fff' },
  ctrlLeave: { background: 'rgba(255,80,80,.1)', borderColor: 'rgba(255,80,80,.3)', color: 'var(--danger)' },
  aiChip: { display: 'flex', alignItems: 'center', gap: 7, fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '.12em', textTransform: 'uppercase', color: 'var(--muted)', padding: '8px 14px', borderRadius: 20, border: '1px solid var(--border2)', background: 'var(--surface)', transition: 'border-color .2s, color .2s' },
  aiChipDot: { width: 6, height: 6, borderRadius: '50%', flexShrink: 0, transition: 'background .2s' },
  aiChipSpeak:  { color: 'var(--ai-ring)', borderColor: 'var(--ai-ring)' },
  aiChipThink:  { color: '#f0c060', borderColor: '#f0c06040' },
  aiChipListen: { color: 'var(--accent)', borderColor: 'rgba(200,240,96,.3)' },
}
