import { useState, useEffect, useCallback, useRef } from 'react';
import type { GuessEntry } from '@wordle/shared';
import { Grid } from '../components/Grid.js';
import { Keyboard } from '../components/Keyboard.js';
import { getMessages } from '../messages/index.js';
import { LangSwitch } from '../components/LangSwitch.js';
import { getValidateWord } from '../api.js';

interface Screen2GameProps {
  guesses: GuessEntry[];
  letterColors: Record<string, string | undefined>;
  message: string | null;
  onGuess: (guess: string) => Promise<boolean>;
  onDismissMessage: () => void;
  gameOver: boolean;
}

export function Screen2Game({ guesses, letterColors, message, onGuess, onDismissMessage, gameOver }: Screen2GameProps) {
  const [currentGuess, setCurrentGuess] = useState<string>('');
  const [cursorPos, setCursorPos] = useState<number>(0);
  const [isValidWord, setIsValidWord] = useState<boolean | null>(null);

  // Track in-flight validation to ignore stale responses
  const validatingWord = useRef<string | null>(null);

  // Reset cursor when guess is cleared (after successful submission)
  useEffect(() => {
    if (currentGuess.length === 0) setCursorPos(0);
  }, [currentGuess]);

  // Auto-dismiss message after 2 seconds
  useEffect(() => {
    if (!message) return;
    const timer = setTimeout(onDismissMessage, 2000);
    return () => clearTimeout(timer);
  }, [message, onDismissMessage]);

  // Validate word on change (debounced via ref)
  useEffect(() => {
    if (currentGuess.length !== 5) {
      setIsValidWord(null);
      return;
    }
    const word = currentGuess;
    validatingWord.current = word;
    getValidateWord(word).then((res) => {
      // Only apply if the guess hasn't changed since the request fired
      if (validatingWord.current === word) {
        setIsValidWord(res.valid);
      }
    }).catch(() => {
      // Network error — don't block submission, let server validate
      if (validatingWord.current === word) {
        setIsValidWord(null);
      }
    });
  }, [currentGuess]);

  const submitCurrent = useCallback(async () => {
    if (currentGuess.length !== 5 || gameOver) return;
    // If we know the word is invalid, don't submit
    if (isValidWord === false) return;
    const accepted = await onGuess(currentGuess);
    if (accepted) {
      setCurrentGuess('');
      setCursorPos(0);
      setIsValidWord(null);
    }
  }, [currentGuess, onGuess, gameOver, isValidWord]);

  // Physical keyboard handler
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (gameOver) return;

      if (e.key === 'Enter') {
        e.preventDefault();
        submitCurrent();
        return;
      }
      if (e.key === 'Backspace') {
        e.preventDefault();
        if (message) onDismissMessage();
        if (cursorPos === 0) return;
        const cp = cursorPos;
        const newPos = cp - 1;
        setCursorPos(newPos);
        setCurrentGuess((prev) => prev.slice(0, newPos) + prev.slice(cp));
        return;
      }
      if (e.key === 'ArrowLeft') {
        e.preventDefault();
        setCursorPos((p) => Math.max(0, p - 1));
        return;
      }
      if (e.key === 'ArrowRight') {
        e.preventDefault();
        setCursorPos((p) => Math.min(currentGuess.length, p + 1));
        return;
      }
      if (/^[a-zA-Z]$/.test(e.key)) {
        const letter = e.key.toLowerCase();
        const cp = cursorPos;
        setCurrentGuess((prev) => {
          if (cp < prev.length) {
            const newGuess = prev.slice(0, cp) + letter + prev.slice(cp + 1);
            setCursorPos(cp + 1);
            return newGuess;
          } else if (prev.length < 5) {
            setCursorPos(cp + 1);
            return prev + letter;
          }
          return prev;
        });
      }
    };

    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [currentGuess, cursorPos, message, gameOver, submitCurrent, onDismissMessage]);

  // On-screen keyboard handler
  const handleKeyPress = useCallback(
    (key: string) => {
      if (gameOver) return;

      if (key === 'Enter') {
        submitCurrent();
      } else if (key === 'Backspace') {
        if (message) onDismissMessage();
        if (cursorPos === 0) return;
        const cp = cursorPos;
        const newPos = cp - 1;
        setCursorPos(newPos);
        setCurrentGuess((prev) => prev.slice(0, newPos) + prev.slice(cp));
      } else if (key === 'ArrowLeft') {
        setCursorPos((p) => Math.max(0, p - 1));
      } else if (key === 'ArrowRight') {
        setCursorPos((p) => Math.min(currentGuess.length, p + 1));
      } else {
        // Letter key
        const letter = key.toLowerCase();
        const cp = cursorPos;
        setCurrentGuess((prev) => {
          if (cp < prev.length) {
            const newGuess = prev.slice(0, cp) + letter + prev.slice(cp + 1);
            setCursorPos(cp + 1);
            return newGuess;
          } else if (prev.length < 5) {
            setCursorPos(cp + 1);
            return prev + letter;
          }
          return prev;
        });
      }
    },
    [currentGuess, cursorPos, message, gameOver, submitCurrent, onDismissMessage]
  );

  const enterDisabled = currentGuess.length !== 5 || isValidWord === false;

  return (
    <div style={{ maxWidth: '400px', margin: '20px auto', padding: '8px', fontFamily: 'sans-serif', position: 'relative' }}>
      <LangSwitch />
      <h1 style={{ textAlign: 'center', fontSize: '1.6rem', marginBottom: '16px' }}>{getMessages().title}</h1>

      <div style={{ position: 'relative' }}>
        <Grid
          guesses={[...guesses, currentGuess ? { guess: currentGuess, colors: [] } : null].filter(Boolean) as GuessEntry[]}
          cursorPos={currentGuess.length > 0 ? cursorPos : undefined}
          onCursorMove={setCursorPos}
        />

        {message && (
          <div
            style={{
              position: 'absolute',
              top: '50%',
              left: '50%',
              transform: 'translate(-50%, -50%)',
              backgroundColor: '#333',
              color: '#fff',
              padding: '8px 16px',
              borderRadius: '6px',
              fontSize: '0.9rem',
              fontWeight: 'bold',
              zIndex: 10,
              whiteSpace: 'nowrap',
            }}
          >
            {message}
          </div>
        )}
      </div>

      <Keyboard letterColors={letterColors} onKeyPress={handleKeyPress} enterDisabled={enterDisabled} />
    </div>
  );
}
