/**
 * Pure helper functions for computing player dot states and styles.
 * These functions are extracted from player.jsx to enable direct testing.
 */

/**
 * Computes the six boolean state flags for a player dot based on current and previous frame data.
 *
 * @param {Object} playerData - The player data object from the WebSocket payload
 * @param {number|null} prevAmmo - The previous frame's ammo count (null on first render)
 * @param {number|null} prevHealth - The previous frame's health value (null on first render)
 * @param {Object} settings - The radar settings object
 * @returns {Object} An object with six boolean flags: isDead, isFlashed, isActive, isShooting, isHurting, isBomb
 */
export function computePlayerStates(playerData, prevAmmo, prevHealth, settings) {
  const showStates = settings?.showDotStates !== false;
  const isDead     = playerData.m_is_dead;

  if (isDead || !showStates) {
    return {
      isDead,
      isFlashed:  false,
      isActive:   false,
      isShooting: false,
      isHurting:  false,
      isBomb:     false,
    };
  }

  const flashAlpha  = playerData.m_flash_alpha ?? 0;
  const currentAmmo = playerData.m_weapons?.m_ammo_clip ?? 0;
  const currentHp   = playerData.m_health ?? 0;
  const activeWpn   = playerData.m_weapons?.m_active ?? "";

  const isFirearm = activeWpn !== "" &&
    !["knife","c4","hegrenade","flashbang","smokegrenade",
      "molotov","incgrenade","decoy","taser","medkit"].some(
        n => activeWpn.startsWith(n));

  return {
    isDead:     false,
    isFlashed:  flashAlpha > 0.125,
    isActive:   playerData.m_is_observed === true,
    isShooting: isFirearm && prevAmmo !== null && currentAmmo < prevAmmo,
    isHurting:  prevHealth !== null && currentHp < prevHealth,
    isBomb:     playerData.m_has_bomb === true,
  };
}

/**
 * Computes the inline style object for the main player dot div based on state flags.
 *
 * @param {Object} states - The state flags object returned by computePlayerStates
 * @param {string} teamColor - The team color hex string (e.g., "#84c8ed")
 * @param {number} dotVw - The dot size in vw units
 * @returns {Object} An inline style object with clipPath, opacity, zIndex, background, borderRadius, and boxShadow
 */
export function computeDotStyle(states, teamColor, dotVw) {
  const { isDead, isFlashed, isActive, isBomb } = states;

  if (isDead) {
    return {
      clipPath: "polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%)",
      opacity:  0.4,
      zIndex:   13,
      background: teamColor,
      borderRadius: "50%",
    };
  }

  const BASE_SHADOW   = `0 0 0 0.05vw rgba(0,0,0,0.8), 0 0 ${dotVw * 3}px ${teamColor}55`;
  const ACTIVE_SHADOW = "0 0 0 0.2vmin rgba(0,0,0,0.9), 0 0 0 1vmin rgba(255,255,255,0.9), 0 0 2.4vmin 1.2vmin rgba(255,255,255,0.2)";
  const FLASH_SHADOW  = "inset 0 0 2vmin 1vmin rgba(255,255,255,0.8)";

  let boxShadow;
  if (isActive && isFlashed)
    boxShadow = `${ACTIVE_SHADOW}, ${FLASH_SHADOW}`;
  else if (isActive)
    boxShadow = ACTIVE_SHADOW;
  else if (isFlashed)
    boxShadow = `${BASE_SHADOW}, ${FLASH_SHADOW}`;
  else
    boxShadow = BASE_SHADOW;

  return {
    clipPath:     "none",
    opacity:      1,
    zIndex:       isActive ? 7000 : 10,
    background:   isBomb ? "#FF8200" : teamColor,
    borderRadius: isBomb ? "2vmin 0.4vmin 2vmin 2.4vmin" : "50%",
    boxShadow,
  };
}
