import { useEffect, useState, useCallback } from "react";
import confetti from 'canvas-confetti';

// Styles
import '../styles/styles.css';

// Types
type GameSession = {
  id: number;
  hint: string;
  totalHints: number;
  digits: number;
  answer: number;
  link?: string;
};

type GuessResponse = {
  correct: boolean;
  feedback: string;
  nextHint: string | null;
  explanation: string | null;
};

type FeedbackType = "default" | "correct" | "misplaced" | "wrong";

type PreviousGuess = {
  digits: string[];
  feedback: FeedbackType[];
};

export default function MultiHintGame() {
  const [session, setSession] = useState<GameSession | null>(null);
  const [currentRound, setCurrentRound] = useState(0);
  const [digitCount, setDigitCount] = useState(4);
  const [digits, setDigits] = useState<string[]>([]);
  const [activeIndex, setActiveIndex] = useState(0);
  const [digitFeedback, setDigitFeedback] = useState<FeedbackType[]>([]);
  const [feedback, setFeedback] = useState<string | null>(null);
  const [nextHint, setNextHint] = useState<string | null>(null);
  const [explanation, setExplanation] = useState<string | null>(null);
  const [gameOver, setGameOver] = useState(false);
  const [previousGuesses, setPreviousGuesses] = useState<PreviousGuess[]>([]);
  const [hasWon, setHasWon] = useState(false);
  const [cooldownRemaining, setCooldownRemaining] = useState(0);

  const [streak, setStreak] = useState(0);
  const [maxStreak, setMaxStreak] = useState(0);

  const COOLDOWN_MS = 6 * 60 * 60 * 1000; // 6 Stunden (für Demo: 6 * 1000 möglich)
  const DEV_MODE = true;


  const updateStreak = () => {
    const today = new Date().toISOString().split("T")[0];
    const lastPlayed = localStorage.getItem("lastPlayedDate");
    let currentStreak = parseInt(localStorage.getItem("streakCount") || "0");
    let max = parseInt(localStorage.getItem("maxStreak") || "0");

    const yesterday = new Date();
    yesterday.setDate(yesterday.getDate() - 1);
    const yesterdayStr = yesterday.toISOString().split("T")[0];

    if (lastPlayed === yesterdayStr) {
      currentStreak += 1;
    } else if (lastPlayed !== today) {
      currentStreak = 1;
    }

    if (currentStreak > max) {
      max = currentStreak;
      localStorage.setItem("maxStreak", max.toString());
    }

    localStorage.setItem("lastPlayedDate", today);
    localStorage.setItem("streakCount", currentStreak.toString());

    setStreak(currentStreak);
    setMaxStreak(max);
  };





const isStillCooldown = useCallback((): boolean => {
  if (DEV_MODE) return false; // ← nie cooldown
  const cooldownUntil = localStorage.getItem("cooldownUntil");
  return cooldownUntil ? parseInt(cooldownUntil) > Date.now() : false;
}, []);


  const getCooldownRemaining = useCallback(() => {
    const cooldownUntil = localStorage.getItem("cooldownUntil");
    return cooldownUntil ? Math.max(0, parseInt(cooldownUntil) - Date.now()) : 0;
  }, []);

const canPlayDailyChallenge = useCallback((): boolean => {
  if (DEV_MODE) return true; // ← erlaubt immer spielen
  const lastPlayed = localStorage.getItem("lastDailyChallengeDate");
  const today = new Date().toISOString().split("T")[0];
  return !lastPlayed || lastPlayed !== today;
}, []);


  const formatCooldownTime = (ms: number): string => {
    const totalSeconds = Math.floor(ms / 1000);
    const hours = Math.floor(totalSeconds / 3600);
    const minutes = Math.floor((totalSeconds % 3600) / 60);
    const seconds = totalSeconds % 60;
    return `${hours.toString().padStart(2, "0")}:${minutes
      .toString()
      .padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
  };

  const handleShare = () => {
    const attempts = currentRound + 1;
    const shareText = `Für die tägliche Challenge der FaktenZahl habe ich ${attempts} Versuch${attempts > 1 ? 'e' : ''} gebraucht. Wie viele brauchst du? www.faktenzahl.de`;
    if (navigator.share) {
      navigator
        .share({
          title: 'FaktenZahl Ergebnis',
          text: shareText,
        })
        .catch(console.error);
    } else {
      navigator.clipboard.writeText(shareText);
      alert('Ergebnis in die Zwischenablage kopiert!');
    }
  };

  const loadSession = () => {
    if (!canPlayDailyChallenge()) {
      setGameOver(true);
      setSession(null);
      setCooldownRemaining(getCooldownRemaining());
      return;
    }
    fetch(`http://localhost:3000/api/new-session?daily=true`)
      .then((res) => res.json())
      .then((data) => {
        setSession(data);
        setCurrentRound(0);
        setFeedback(null);
        setNextHint(data.hint);
        setExplanation(null);
        setGameOver(false);
        setDigitCount(data.digits);
        setDigits(Array(data.digits).fill(""));
        setDigitFeedback(Array(data.digits).fill("default"));
        setActiveIndex(0);
        setPreviousGuesses([]);
        setHasWon(false);
        localStorage.removeItem("hasWon");
        localStorage.removeItem("explanation");
        localStorage.removeItem("link");
        localStorage.removeItem("currentRound");
        localStorage.setItem("cooldownUntil", (Date.now() + COOLDOWN_MS).toString());
        localStorage.setItem("lastDailyChallengeDate", new Date().toISOString().split("T")[0]);
        setCooldownRemaining(COOLDOWN_MS);
      });
  };

  useEffect(() => {
    const stillCooldown = isStillCooldown();
    setCooldownRemaining(getCooldownRemaining());

    // Lese hasWon, explanation, link und currentRound aus localStorage
    const storedHasWon = localStorage.getItem("hasWon");
    const storedExplanation = localStorage.getItem("explanation");
    const storedCurrentRound = localStorage.getItem("currentRound");
    setHasWon(storedHasWon === "true");
    setExplanation(storedExplanation || null);
    if (storedCurrentRound) {
      setCurrentRound(parseInt(storedCurrentRound));
    }

    if (stillCooldown || !canPlayDailyChallenge()) {
      setGameOver(true);
      setSession(null);
    } else {
      loadSession();
    }
  }, [isStillCooldown, canPlayDailyChallenge]);

  useEffect(() => {
    if (gameOver && cooldownRemaining > 0) {
      const interval = setInterval(() => {
        const remaining = getCooldownRemaining();
        setCooldownRemaining(remaining);
        if (remaining <= 0) {
          setGameOver(false);
          localStorage.removeItem("cooldownUntil");
          localStorage.removeItem("hasWon");
          localStorage.removeItem("explanation");
          localStorage.removeItem("link");
          localStorage.removeItem("currentRound");
          loadSession();
        }
      }, 1000);
      return () => clearInterval(interval);
    }
  }, [cooldownRemaining, getCooldownRemaining, gameOver]);

  const handleDigitClick = (num: string) => {
    if (activeIndex >= digitCount) return;
    const newDigits = [...digits];
    newDigits[activeIndex] = num;
    setDigits(newDigits);
    if (activeIndex < digitCount - 1) setActiveIndex(activeIndex + 1);
  };

  const handleBackspace = () => {
    const newDigits = [...digits];
    if (digits[activeIndex]) {
      newDigits[activeIndex] = "";
      setDigits(newDigits);
    } else if (activeIndex > 0) {
      newDigits[activeIndex - 1] = "";
      setDigits(newDigits);
      setActiveIndex(activeIndex - 1);
    }
  };

  const submitGuess = async () => {
    if (!session) return;
    const fullGuess = digits.join("");

    const res = await fetch("http://localhost:3000/api/guess", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        id: session.id,
        guess: fullGuess,
        round: currentRound,
      }),
    });

    const data: GuessResponse = await res.json();
    setFeedback(data.feedback);
    setExplanation(data.explanation);
    setNextHint(data.nextHint);

    const correctAnswer = String(session.answer).split("");
    const feedbackResult: FeedbackType[] = digits.map((digit, index) => {
      if (digit === correctAnswer[index]) return "correct";
      if (correctAnswer.includes(digit)) return "misplaced";
      return "wrong";
    });

    setPreviousGuesses((prev) => [...prev, { digits: [...digits], feedback: feedbackResult }]);
    setDigits(Array(digitCount).fill(""));
    setDigitFeedback(Array(digitCount).fill("default"));
    setActiveIndex(0);

    if (data.correct || currentRound === 4) {
      setGameOver(true);
      setHasWon(data.correct);
      localStorage.setItem("hasWon", String(data.correct));
      localStorage.setItem("explanation", data.explanation || "");
      localStorage.setItem("link", session.link || "");
      localStorage.setItem("currentRound", String(currentRound));

      if (data.correct) {
        localStorage.setItem("cooldownUntil", (Date.now() + COOLDOWN_MS).toString());
        localStorage.setItem("lastDailyChallengeDate", new Date().toISOString().split("T")[0]);
        setCooldownRemaining(COOLDOWN_MS);
        updateStreak();
        confetti({
          particleCount: 120,
          spread: 80,
          origin: { y: 0.6 },
          colors: ['#00d9ff', '#00ff84', '#ffc107', '#ff4ecd'],
        });
      }
    } else {
      setCurrentRound((r) => r + 1);
    }
  };

  const restart = () => {
    if (isStillCooldown() || !canPlayDailyChallenge()) return;
    loadSession();
  };

  const getBoxStyle = (status: FeedbackType) => {
    switch (status) {
      case "correct": return "bg-green-400";
      case "misplaced": return "bg-yellow-300";
      case "wrong": return "bg-red-400";
      default: return "bg-blue-100";
    }
  };

  return (

    
    <div className="w-[480px] mx-auto mt-10 p-6 bg-white dark:bg-gray-800 text-gray-900 dark:text-white rounded-xl shadow">
      <h2 className="text-2xl font-bold mb-4 text-center">
        🧠 Tägliche FaktenZahl ({new Date().toLocaleDateString('de-DE')})
      </h2>

      <div className="text-center mb-4 text-sm text-gray-700 dark:text-gray-300">
      🔥 Aktuelle Streak: <strong>{streak}</strong> &nbsp; | &nbsp; 🏆 Beste Streak: <strong>{maxStreak}</strong>
    </div>


      {session && !gameOver && (
        <>
          <p className="mb-2">Hinweis {currentRound + 1} von {session.totalHints}:</p>
          <div className="mb-4 bg-gray-100 dark:bg-gray-700 rounded p-4 text-center">
            {nextHint}
          </div>

          <div className="flex flex-col gap-2 mb-6">
            {previousGuesses.map((guess, i) => (
              <div key={i} className="flex justify-center gap-2">
                {guess.digits.map((digit, j) => (
                  <div key={j} className={`w-20 h-24 text-4xl font-bold rounded-xl flex items-center justify-center text-white shadow ${getBoxStyle(guess.feedback[j])}`}>{digit}</div>
                ))}
              </div>
            ))}

            <div className="flex justify-center gap-4">
              {digits.map((digit, i) => (
                <div key={i} className={`w-24 h-28 text-6xl font-extrabold rounded-xl flex items-center justify-center shadow-xl text-white ${getBoxStyle(digitFeedback[i])}`} onClick={() => setActiveIndex(i)}>
                  {digit || <span className="opacity-40">–</span>}
                </div>
              ))}
            </div>
          </div>

          <div className="grid grid-cols-3 gap-2 max-w-xs mx-auto mb-4">
            {[1, 2, 3, 4, 5, 6, 7, 8, 9].map(num => (
              <button key={num} onClick={() => handleDigitClick(num.toString())} className="bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500 text-xl py-3 rounded">{num}</button>
            ))}
            <div></div>
            <button onClick={() => handleDigitClick("0")} className="bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500 text-xl py-3 rounded">0</button>
            <div></div>
            <button onClick={handleBackspace} className="col-span-3 bg-red-200 dark:bg-red-400 hover:bg-red-300 dark:hover:bg-red-500 py-3 rounded font-bold">⬅️ Löschen</button>
          </div>

          <button onClick={submitGuess} disabled={digits.includes("")} className="bg-blue-600 dark:bg-blue-500 hover:bg-blue-700 dark:hover:bg-blue-600 text-white px-4 py-2 rounded w-full">Rate Zahl</button>
        </>
      )}

      {gameOver && (
        <div className={`mt-6 p-4 rounded text-center ${hasWon ? "bg-green-100 dark:bg-green-900" : "bg-red-100 dark:bg-red-900"}`}>
          <p className={`text-xl font-bold mb-2 ${hasWon ? "text-green-700 dark:text-green-300" : "text-red-700 dark:text-red-300"}`}>
            {hasWon ? "🎉 Richtig geraten!" : "😢 Leider daneben!"}
          </p>
          <p className="text-gray-800 dark:text-gray-200 mb-2">
            Versuche: {currentRound + 1}
          </p>
          {explanation && <p className="text-gray-800 dark:text-gray-200 mb-2">{explanation}</p>}
          {localStorage.getItem("link") && (
            <a href={localStorage.getItem("link")!} target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 underline block mb-4">
              Mehr erfahren ↗
            </a>
          )}
          {cooldownRemaining > 0 && (
            <>
              <p className="mb-4 text-lg font-bold text-orange-600 dark:text-orange-400 border-2 border-orange-600 dark:border-orange-400 rounded-lg p-2 timer-pulse">
                ⏳ Nächste Frage in: {formatCooldownTime(cooldownRemaining)}
              </p>
              <button
                onClick={handleShare}
                className="mt-2 bg-blue-500 hover:bg-blue-600 text-white px-3 py-2 rounded"
              >
                Teilen 📤
              </button>
            </>
          )}
          {cooldownRemaining <= 0 && (
            <button onClick={restart} className="mt-4 bg-gray-600 hover:bg-gray-700 text-white px-3 py-2 rounded">Neue Runde starten</button>
          )}
        </div>
      )}
    </div>
  );
}