const DEFAULT_COOLDOWNS = {
  work: 3600,
  daily: 72000,
  slots: 60,
  coinflip: 30,
  rep: 43200,
  trivia: 30,
  heist: 1800,
  duel: 300,
  gift: 60,
  trade: 60
};

const userCooldowns = new Map();

const cooldownCache = new Map();
const CACHE_TTL = 5 * 60 * 1000;

async function getCommandCooldown(supabase, guildId, commandName) {
  if (!supabase) {
    return DEFAULT_COOLDOWNS[commandName] || 0;
  }

  const cacheKey = `${guildId}-${commandName}`;
  const cached = cooldownCache.get(cacheKey);
  
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.value;
  }

  try {
    const { data } = await supabase
      .from('command_cooldowns')
      .select('cooldown_seconds')
      .eq('guild_id', guildId)
      .eq('command_name', commandName)
      .maybeSingle();

    const cooldown = data?.cooldown_seconds ?? DEFAULT_COOLDOWNS[commandName] ?? 0;
    
    cooldownCache.set(cacheKey, { value: cooldown, timestamp: Date.now() });
    
    return cooldown;
  } catch (error) {
    console.error('Failed to fetch cooldown:', error.message);
    return DEFAULT_COOLDOWNS[commandName] || 0;
  }
}

function getCooldownKey(guildId, userId, commandName) {
  return `${guildId}-${userId}-${commandName}`;
}

function getUserCooldown(guildId, userId, commandName) {
  const key = getCooldownKey(guildId, userId, commandName);
  return userCooldowns.get(key);
}

function setUserCooldown(guildId, userId, commandName) {
  const key = getCooldownKey(guildId, userId, commandName);
  userCooldowns.set(key, Date.now());
}

function clearUserCooldown(guildId, userId, commandName) {
  const key = getCooldownKey(guildId, userId, commandName);
  userCooldowns.delete(key);
}

async function checkCooldown(supabase, guildId, userId, commandName) {
  const cooldownSeconds = await getCommandCooldown(supabase, guildId, commandName);
  
  if (cooldownSeconds === 0) {
    return { onCooldown: false, cooldownSeconds: 0 };
  }

  const cooldownMs = cooldownSeconds * 1000;
  const lastUsed = getUserCooldown(guildId, userId, commandName);

  if (!lastUsed) {
    return { onCooldown: false, cooldownSeconds };
  }

  const elapsed = Date.now() - lastUsed;
  const remaining = cooldownMs - elapsed;

  if (remaining <= 0) {
    return { onCooldown: false, cooldownSeconds };
  }

  return {
    onCooldown: true,
    remaining: remaining,
    remainingSeconds: Math.ceil(remaining / 1000),
    cooldownSeconds
  };
}

function formatCooldownRemaining(remainingMs) {
  const seconds = Math.ceil(remainingMs / 1000);
  
  if (seconds < 60) {
    return `${seconds}s`;
  }
  
  const minutes = Math.floor(seconds / 60);
  const secs = seconds % 60;
  
  if (minutes < 60) {
    return secs > 0 ? `${minutes}m ${secs}s` : `${minutes}m`;
  }
  
  const hours = Math.floor(minutes / 60);
  const mins = minutes % 60;
  
  if (hours < 24) {
    return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
  }
  
  const days = Math.floor(hours / 24);
  const hrs = hours % 24;
  return hrs > 0 ? `${days}d ${hrs}h` : `${days}d`;
}

function invalidateCooldownCache(guildId, commandName = null) {
  if (commandName) {
    cooldownCache.delete(`${guildId}-${commandName}`);
  } else {
    for (const key of cooldownCache.keys()) {
      if (key.startsWith(`${guildId}-`)) {
        cooldownCache.delete(key);
      }
    }
  }
}

module.exports = {
  getCommandCooldown,
  getUserCooldown,
  setUserCooldown,
  clearUserCooldown,
  checkCooldown,
  formatCooldownRemaining,
  invalidateCooldownCache,
  DEFAULT_COOLDOWNS
};
