import React, { useEffect, useRef, useState, useCallback } from 'react';
import { DraggableWindow } from './DraggableWindow';

interface ChatMsg {
  text: string;
  color?: number;
  timestamp: string;
}

const CHAT_COLORS: Record<number, string> = {
  0:'#00FF00', 2:'#FFFFFF', 3:'#FF0000', 4:'#FFFFFF', 5:'#33CCFF', 6:'#CCFF99',
  7:'#00FFFF', 14:'#FFD700', 15:'#FF69B4', 17:'#AAAAFF', 18:'#88FF88',
  21:'#FF8888', 22:'#FFAA66',
};

const MAX_HISTORY = 50;
const HISTORY_KEY = (name: string) => `mo-chat-history-${name}`;

function loadHistory(charName: string): string[] {
  try {
    const raw = localStorage.getItem(HISTORY_KEY(charName));
    return raw ? JSON.parse(raw) : [];
  } catch { return []; }
}

function saveHistory(charName: string, history: string[]) {
  try {
    localStorage.setItem(HISTORY_KEY(charName), JSON.stringify(history.slice(-MAX_HISTORY)));
  } catch { /* quota exceeded — ignore */ }
}

interface Props {
  id: string;
  charName: string;
  zIndex: number;
  messages: ChatMsg[];
  socket: WebSocket | null;
}

export const ChatWindow: React.FC<Props> = ({ id, charName, zIndex, messages, socket }) => {
  const msgsRef = useRef<HTMLDivElement>(null);
  const [input, setInput] = useState('');
  const historyRef = useRef<string[]>(loadHistory(charName));
  const historyIndexRef = useRef(-1); // -1 = not browsing history
  const savedInputRef = useRef(''); // preserves current input when browsing history
  const userScrolledRef = useRef(false);

  // Auto-scroll only if user is already at the bottom
  useEffect(() => {
    const el = msgsRef.current;
    if (!el) return;
    if (!userScrolledRef.current) {
      el.scrollTop = el.scrollHeight;
    }
  }, [messages.length]);

  // Track whether user has scrolled up from bottom
  const handleScroll = useCallback(() => {
    const el = msgsRef.current;
    if (!el) return;
    const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 30;
    userScrolledRef.current = !atBottom;
  }, []);

  const handleSend = useCallback((e: React.FormEvent) => {
    e.preventDefault();
    const text = input.trim();
    if (!text || !socket || socket.readyState !== WebSocket.OPEN) return;
    socket.send(JSON.stringify({ player_name: charName, command: text }));

    // Add to history
    historyRef.current.push(text);
    if (historyRef.current.length > MAX_HISTORY) historyRef.current.shift();
    saveHistory(charName, historyRef.current);
    historyIndexRef.current = -1;
    savedInputRef.current = '';

    setInput('');

    // Snap back to bottom on send
    userScrolledRef.current = false;
  }, [input, socket, charName]);

  const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
    const history = historyRef.current;
    if (history.length === 0) return;

    if (e.key === 'ArrowUp') {
      e.preventDefault();
      if (historyIndexRef.current === -1) {
        // Starting to browse — save current input
        savedInputRef.current = input;
        historyIndexRef.current = history.length - 1;
      } else if (historyIndexRef.current > 0) {
        historyIndexRef.current--;
      }
      setInput(history[historyIndexRef.current]);
    } else if (e.key === 'ArrowDown') {
      e.preventDefault();
      if (historyIndexRef.current === -1) return; // not browsing
      if (historyIndexRef.current < history.length - 1) {
        historyIndexRef.current++;
        setInput(history[historyIndexRef.current]);
      } else {
        // Past the end — restore saved input
        historyIndexRef.current = -1;
        setInput(savedInputRef.current);
      }
    }
  }, [input]);

  return (
    <DraggableWindow id={id} title={`Chat: ${charName}`} zIndex={zIndex} width={600} height={300}>
      <div className="ml-chat-messages" ref={msgsRef} onScroll={handleScroll}>
        {messages.map((m, i) => (
          <div key={i} className="ml-chat-line" style={{ color: CHAT_COLORS[m.color ?? 2] ?? '#ddd' }}>
            {m.text}
          </div>
        ))}
      </div>
      <form className="ml-chat-form" onSubmit={handleSend}>
        <input className="ml-chat-input" value={input} onChange={e => setInput(e.target.value)}
          onKeyDown={handleKeyDown} placeholder="Enter chat..." />
      </form>
    </DraggableWindow>
  );
};
