'use client';

import { useEffect, useState } from 'react';
import './typing-words.css';

const WORDS = ['plan', 'idea', 'problem', 'goals'] as const;

const TYPING_MS = 90;
const DELETING_MS = 55;
const PAUSE_AFTER_TYPED_MS = 2000;
const PAUSE_AFTER_DELETED_MS = 400;

type Phase = 'typing' | 'pausing' | 'deleting' | 'waiting';

export default function TypingWords() {
  const [wordIndex, setWordIndex] = useState(0);
  const [charIndex, setCharIndex] = useState(0);
  const [phase, setPhase] = useState<Phase>('typing');
  const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);

  useEffect(() => {
    const media = window.matchMedia('(prefers-reduced-motion: reduce)');
    setPrefersReducedMotion(media.matches);

    const onChange = () => setPrefersReducedMotion(media.matches);
    media.addEventListener('change', onChange);
    return () => media.removeEventListener('change', onChange);
  }, []);

  useEffect(() => {
    if (prefersReducedMotion) return;

    const currentWord = WORDS[wordIndex];
    let timeoutId: ReturnType<typeof setTimeout>;

    if (phase === 'typing') {
      if (charIndex < currentWord.length) {
        timeoutId = setTimeout(() => setCharIndex((i) => i + 1), TYPING_MS);
      } else {
        timeoutId = setTimeout(() => setPhase('pausing'), PAUSE_AFTER_TYPED_MS);
      }
    } else if (phase === 'pausing') {
      timeoutId = setTimeout(() => setPhase('deleting'), 0);
    } else if (phase === 'deleting') {
      if (charIndex > 0) {
        timeoutId = setTimeout(() => setCharIndex((i) => i - 1), DELETING_MS);
      } else {
        timeoutId = setTimeout(() => {
          setWordIndex((i) => (i + 1) % WORDS.length);
          setPhase('waiting');
        }, PAUSE_AFTER_DELETED_MS);
      }
    } else if (phase === 'waiting') {
      timeoutId = setTimeout(() => setPhase('typing'), 0);
    }

    return () => clearTimeout(timeoutId);
  }, [charIndex, phase, wordIndex, prefersReducedMotion]);

  useEffect(() => {
    if (!prefersReducedMotion) return;

    const intervalId = setInterval(() => {
      setWordIndex((i) => (i + 1) % WORDS.length);
    }, 3000);

    return () => clearInterval(intervalId);
  }, [prefersReducedMotion]);

  const displayedWord = prefersReducedMotion
    ? WORDS[wordIndex]
    : WORDS[wordIndex].slice(0, charIndex);

  return (
    <span className="typing-words" aria-live="polite">
      <span className="typing-words-text text-transparent bg-clip-text bg-gradient-to-r from-sky-400 to-violet-800">
        {displayedWord}
      </span>
      <span className="typing-words-cursor" aria-hidden="true">
        |
      </span>
    </span>
  );
}
