import { useEffect, useState } from "react";
import {
  dispatch,
  useGameId,
  useIsMuted,
  usePlayerName,
} from "../../../domain/gameStore";
import { usePlayers } from "../../../hooks/useGameInfo";
import styles from "./KillFeed.module.css";
import hitmarker from "../../../assets/hitmarker.svg";
import hitsound from "../../../assets/hitsound.wav";

// okay, in an ideal world this would be part of the game store or something
// and it would get properly managed by reactive state
// but also, this totally works as is, and the only downside is it might potentially grow too big
// but that only happens if someone plays that many gun games without ever leaving the window
const shownItems = new Set();

const KillFeed = () => {
  const muted = useIsMuted();
  const playerName = usePlayerName();
  const gameId = useGameId();
  const players = usePlayers();
  useEffect(() => {
    if (players?.find(({ currentRound }) => currentRound === null)) {
      dispatch.goToSummary();
    }
  }, [players]);
  const [shownItemsState, setShownItemsState] = useState(shownItems);
  const [display, setDisplay] = useState([]);
  useEffect(() => {
    const toDisplay =
      players
        ?.filter(({ name }) => name !== playerName)
        ?.flatMap(({ name, guesses }) =>
          Object.entries(guesses).map(([round, { score }]) => ({
            name,
            round,
            score,
          }))
        )
        ?.filter(
          ({ name, round }) =>
            !shownItemsState.has(`${gameId}-${name}-${round}`)
        ) ?? [];
    setDisplay(toDisplay);
    const timeout = setTimeout(() => {
      toDisplay.forEach(({ name, round }) => {
        shownItems.add(`${gameId}-${name}-${round}`);
      });
      setShownItemsState(new Set(shownItems));
    }, 5000);
    return () => {
      clearTimeout(timeout);
    };
  }, [shownItemsState, gameId, players, playerName]);
  useEffect(() => {
    if (!muted) {
      display.forEach(() => {
        const audio = new Audio(hitsound);
        audio.volume = 0.5;
        // delay up to half a second so overlapping sounds better
        const delayedPlay = () =>
          setTimeout(() => audio.play(), Math.random() * 500);
        audio.addEventListener("canplaythrough", delayedPlay);
        // clean up after ourselves in the hopes that the browser actually deletes this audio element
        audio.addEventListener("ended", () =>
          audio.removeEventListener("canplaythrough", delayedPlay)
        );
      });
    }
  }, [display, muted]);
  return (
    <>
      {display.map(() => (
        <img
          alt="hitmarker"
          className={styles.hitmarker}
          style={{
            top: `${10 + Math.random() * 80}vh`,
            left: `${10 + Math.random() * 80}vw`,
          }}
          src={hitmarker}
        />
      ))}
      <div className={styles.feed}>
        {display.map(({ name, round, score }) => (
          <span className={styles.item}>
            <span className={styles.name}>{name}</span>{" "}
            {score >= 4950 ? "🎯" : "🖱️"} 🗺️ {round}
          </span>
        ))}
      </div>
    </>
  );
};

export default KillFeed;
