import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useToasts } from './Toasts.jsx';

export default function Chat({ socket, roomId, name, isHost, members }) {
  const { push } = useToasts();
  const [messages, setMessages] = useState([]);
  const [text, setText] = useState('');
  const inputRef = useRef(null);
  const logRef = useRef(null);

  const [showMentions, setShowMentions] = useState(false);
  const [mentionQuery, setMentionQuery] = useState('');
  const [mentionAtIndex, setMentionAtIndex] = useState(-1);

  const mentionCandidates = useMemo(() => {
    const q = (mentionQuery || '').toLowerCase();
    return (members || []).filter(m => m.name.toLowerCase().includes(q)).slice(0, 8);
  }, [mentionQuery, members]);

  useEffect(() => {
    const onMsg = (m) => setMessages((prev) => [...prev, m]);
    const onSys = (m) => setMessages((prev) => [...prev, { name: 'System', text: m.text || 'System message', at: Date.now(), system: true }]);
    socket.on('chat_message', onMsg);
    socket.on('system', onSys);
    return () => { socket.off('chat_message', onMsg); socket.off('system', onSys); };
  }, [socket]);

  useEffect(() => {
    if (logRef.current) logRef.current.scrollTop = logRef.current.scrollHeight;
  }, [messages]);

  const parseCommand = (t) => {
    const raw = t.trim();
    const lower = raw.toLowerCase();
    if (lower.startsWith('/play ')) return { cmd: 'play', arg: raw.slice(6).trim() };
    if (lower.startsWith('/kick ')) return { cmd: 'kick', arg: raw.slice(6).trim().replace(/^@/, '') };
    if (lower.startsWith('/promote ')) return { cmd: 'promote', arg: raw.slice(9).trim().replace(/^@/, '') };
    if (lower.startsWith('/mute ')) return { cmd: 'mute', arg: raw.slice(6).trim().replace(/^@/, '') };
    return null;
  };

  const handleSend = () => {
    const t = text.trim();
    if (!t) return;

    const parsed = parseCommand(t);
    if (parsed) {
      if (parsed.cmd === 'play') {
        const query = parsed.arg;
        if (!query) return;
        socket.emit('song_request', { roomId, requester: name, query });
        setMessages(prev => [...prev, { name: 'You', text: `Requested: ${query}`, at: Date.now(), system: true }]);
        setText('');
        setShowMentions(false);
        return;
      }
      if (parsed.cmd === 'kick' || parsed.cmd === 'promote' || parsed.cmd === 'mute') {
        if (!isHost) push('Only host/co-host can run admin commands', 'warn');
        else if (!parsed.arg) push('Provide a username like /kick @username', 'warn');
        else socket.emit('admin_command', { roomId, cmd: parsed.cmd, targetName: parsed.arg });
        setText('');
        setShowMentions(false);
        return;
      }
    }

    const m = { name, text: t, at: Date.now() };
    setMessages((prev) => [...prev, m]);
    socket.emit('chat_message', { roomId, name, text: t });
    setText('');
    setShowMentions(false);
  };

  const onInputChange = (e) => {
    const val = e.target.value;
    const caret = e.target.selectionStart ?? val.length;
    setText(val);

    let at = -1;
    for (let i = caret - 1; i >= 0; i--) {
      if (val[i] === '@') { at = i; break; }
      if (/\s/.test(val[i])) break;
    }
    if (at >= 0) {
      const q = val.slice(at + 1, caret);
      setMentionAtIndex(at);
      setMentionQuery(q);
      setShowMentions(true);
    } else {
      setShowMentions(false);
      setMentionAtIndex(-1);
      setMentionQuery('');
    }
  };

  const chooseMention = (m) => {
    if (!inputRef.current) return;
    const el = inputRef.current;
    const val = text;
    const caret = el.selectionStart ?? val.length;
    const at = mentionAtIndex >= 0 ? mentionAtIndex : val.lastIndexOf('@', caret);
    if (at < 0) return;

    const before = val.slice(0, at);
    const nextSpace = val.slice(at + 1).search(/\s/);
    const end = nextSpace < 0 ? val.length : (at + 1 + nextSpace);
    const after = val.slice(end);

    const inserted = `${before}@${m.name} `;
    const nextVal = inserted + after;
    setText(nextVal);

    const newPos = inserted.length;
    setTimeout(() => { el.focus(); el.setSelectionRange(newPos, newPos); }, 0);

    setShowMentions(false);
    setMentionQuery('');
    setMentionAtIndex(-1);
  };

  return (
    <div className="chat" style={{ position: 'relative' }}>
      <div ref={logRef} className="chat-log">
        {messages.map((m, i) => (
          <div key={i} style={{ marginBottom:6 }}>
            <b style={{ color: m.system ? 'var(--accent)' : 'var(--accent-2)' }}>{m.name}:</b> {m.text}
          </div>
        ))}
      </div>
      <div className="chat-input">
        <input
          ref={inputRef}
          className="input"
          value={text}
          onChange={onInputChange}
          placeholder="Type — /play <song>, /kick @user, /promote @user, /mute @user"
        />
        <button className="btn primary" onClick={handleSend}>Send</button>
      </div>

      {showMentions && (
        <div className="mentions" style={{ left: 8, bottom: 52 }}>
          {mentionCandidates.length ? mentionCandidates.map(m => (
            <div key={m.id} className="item" onClick={() => chooseMention(m)}>
              @{m.name} {m.role !== 'member' ? `(${m.role})` : ''}
            </div>
          )) : <div className="item" style={{ opacity:.7 }}>No matches</div>}
        </div>
      )}
    </div>
  );
}
