import { GameConfig } from "./config.js";

/**
 * @param {number} baseCost
 * @param {number} growth
 * @param {number} level
 * @returns {number}
 */
export function exponentialCost(baseCost, growth, level) {
  const exponent = Math.max(0, level - 1);
  return Math.floor(baseCost * Math.pow(growth, exponent) + 0.5);
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getConveyorUpgradeCost(currentLevel) {
  return exponentialCost(
    GameConfig.Conveyor.BaseUpgradeCost,
    GameConfig.Conveyor.UpgradeGrowth,
    currentLevel
  );
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getTruckUpgradeCost(currentLevel) {
  return exponentialCost(
    GameConfig.Truck.BaseUpgradeCost,
    GameConfig.Truck.UpgradeGrowth,
    currentLevel
  );
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getSchoolUpgradeCost(currentLevel) {
  return exponentialCost(
    GameConfig.School.BaseUpgradeCost,
    GameConfig.School.UpgradeGrowth,
    currentLevel
  );
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getWorldMapUpgradeCost(currentLevel) {
  const cfg = GameConfig.WorldMap && GameConfig.WorldMap.MapUpgrade;
  if (!cfg) return 9999;
  return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel);
}

/**
 * Research points required to upgrade world map level (phase 9: agrandissement en unités de recherche).
 * @param {number} currentLevel
 * @returns {number}
 */
export function getWorldMapUpgradeResearchCost(currentLevel) {
  const cfg = GameConfig.WorldMap && GameConfig.WorldMap.MapUpgrade;
  if (!cfg || cfg.BaseResearchCost === null || cfg.BaseResearchCost === undefined) return 9999;
  const growth = cfg.ResearchUpgradeGrowth ?? 1.6;
  return exponentialCost(cfg.BaseResearchCost, growth, currentLevel);
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getPlotUpgradeCost(currentLevel) {
  return exponentialCost(
    GameConfig.Plot.BaseUpgradeCost,
    GameConfig.Plot.UpgradeGrowth,
    currentLevel
  );
}

/**
 * @returns {number}
 */
export function getNurseryBuildCost() {
  return GameConfig.Nursery?.BuildCost ?? 200;
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getNurseryUpgradeCost(currentLevel) {
  const cfg = GameConfig.Nursery;
  if (!cfg) return 9999;
  return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel);
}

/**
 * @returns {number}
 */
export function getSouvenirShopBuildCost() {
  return GameConfig.SouvenirShop?.BuildCost ?? 250;
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getSouvenirShopUpgradeCost(currentLevel) {
  const cfg = GameConfig.SouvenirShop;
  if (!cfg) return 9999;
  return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel);
}

/**
 * @returns {number}
 */
export function getResearchBuildCost() {
  return GameConfig.Research?.BuildCost ?? 300;
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getResearchUpgradeCost(currentLevel) {
  const cfg = GameConfig.Research;
  if (!cfg) return 9999;
  return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel);
}

/**
 * @returns {number}
 */
export function getBilleterieBuildCost() {
  return GameConfig.Billeterie?.BuildCost ?? 280;
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getBilleterieUpgradeCost(currentLevel) {
  const cfg = GameConfig.Billeterie;
  if (!cfg) return 9999;
  return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel);
}

/**
 * @returns {number}
 */
export function getFoodBuildCost() {
  return GameConfig.Food?.BuildCost ?? 260;
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getFoodUpgradeCost(currentLevel) {
  const cfg = GameConfig.Food;
  if (!cfg) return 9999;
  return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel);
}

/**
 * @returns {number}
 */
export function getReceptionBuildCost() {
  return GameConfig.Reception?.BuildCost ?? 240;
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getReceptionUpgradeCost(currentLevel) {
  const cfg = GameConfig.Reception;
  if (!cfg) return 9999;
  return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel);
}

/**
 * @returns {number}
 */
export function getBiomeChangeColorBuildCost() {
  return GameConfig.BiomeChangeColor?.BuildCost ?? 340;
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getBiomeChangeColorUpgradeCost(currentLevel) {
  const cfg = GameConfig.BiomeChangeColor;
  if (!cfg) return 9999;
  return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel);
}

/**
 * @returns {number}
 */
export function getBiomeChangeTempBuildCost() {
  return GameConfig.BiomeChangeTemp?.BuildCost ?? 340;
}

/**
 * @param {number} currentLevel
 * @returns {number}
 */
export function getBiomeChangeTempUpgradeCost(currentLevel) {
  const cfg = GameConfig.BiomeChangeTemp;
  if (!cfg) return 9999;
  return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel);
}

/** Building kinds that use the same build/upgrade pattern (7 levels). */
export const BUILDING_KINDS = [
  "research",
  "billeterie",
  "food",
  "reception",
  "biomeChangeColor",
  "biomeChangeTemp",
];

/**
 * @param {typeof BUILDING_KINDS[number]} kind
 * @returns {number}
 */
export function getBuildingBuildCost(kind) {
  switch (kind) {
    case "research":
      return getResearchBuildCost();
    case "billeterie":
      return getBilleterieBuildCost();
    case "food":
      return getFoodBuildCost();
    case "reception":
      return getReceptionBuildCost();
    case "biomeChangeColor":
      return getBiomeChangeColorBuildCost();
    case "biomeChangeTemp":
      return getBiomeChangeTempBuildCost();
    default:
      return 9999;
  }
}

/**
 * @param {typeof BUILDING_KINDS[number]} kind
 * @param {number} currentLevel
 * @returns {number}
 */
export function getBuildingUpgradeCost(kind, currentLevel) {
  switch (kind) {
    case "research":
      return getResearchUpgradeCost(currentLevel);
    case "billeterie":
      return getBilleterieUpgradeCost(currentLevel);
    case "food":
      return getFoodUpgradeCost(currentLevel);
    case "reception":
      return getReceptionUpgradeCost(currentLevel);
    case "biomeChangeColor":
      return getBiomeChangeColorUpgradeCost(currentLevel);
    case "biomeChangeTemp":
      return getBiomeChangeTempUpgradeCost(currentLevel);
    default:
      return 9999;
  }
}

/**
 * @param {typeof BUILDING_KINDS[number]} kind
 * @returns {number}
 */
export function getBuildingMaxLevel(kind) {
  const key = kind.charAt(0).toUpperCase() + kind.slice(1);
  const cfg = GameConfig[key];
  return cfg?.MaxLevel ?? 7;
}

/**
 * @param {number} level
 * @returns {number}
 */
export function getLevelMultiplier(level) {
  const current = level ?? 1;
  return 1 + 0.1 * Math.max(0, current - 1);
}

/**
 * @param {number} baseIncomePerSecond
 * @param {number} level
 * @param {number} mutationMultiplier
 * @param {number} sellFactor
 * @returns {number}
 */
export function getSellValue(baseIncomePerSecond, level, mutationMultiplier, sellFactor) {
  const levelMult = getLevelMultiplier(level);
  return Math.floor(baseIncomePerSecond * mutationMultiplier * levelMult * sellFactor + 0.5);
}
