import { ITEM_TYPES } from "../constants.js";
import { RdDItem } from "../item.js";
import { Misc } from "../misc.js";
import { LIST_CARAC_PERSONNAGE, RdDCarac } from "../rdd-carac.js";

const _warn = msg => ui.notifications?.warn(msg)

export class RdDItemRace extends RdDItem {

  static get ITEM_TYPE() { return ITEM_TYPES.race }

  static get defaultIcon() {
    return "systems/foundryvtt-reve-de-dragon/icons/humanoides/humain.webp";
  }

  static checkRacialMax(actor, code, value) {
    const race = RdDItemRace.getRace(actor)
    if (code == LIST_CARAC_PERSONNAGE.force.code) {
      if (!race.isForceValid(actor, value)) {
        _warn(race.system.carac.force.limitmessage)
        return false
      }
    }
    if (code == LIST_CARAC_PERSONNAGE.taille.code) {
      const carac = RdDCarac.carac(code)
      if (race.isMax(actor, code, value - 1)) {
        _warn(`${value} est supérieure au maximum de ${carac.label}`)
        return false
      }
    }
    return true
  }

  static applyRacialLimits(actor) {
    const race = RdDItemRace.getRace(actor)
    actor.system.carac.taille.value = race.getValidTaille(actor.getTaille())
    actor.system.carac.force.value = Math.min(
      actor.getForce(),
      race.getForceMax(actor))
  }

  static isRacialMax(actor, code, value = undefined) {
    return RdDItemRace.getRace(actor).isMax(actor, code, value)
  }

  static getRace(actor) {
    return actor.itemTypes[ITEM_TYPES.race].find(it => true) ?? RdDItemRace.getFallbackRace()
  }

  static getFallbackRace() {
    if (RdDItemRace.fallback == undefined) {
      RdDItemRace.fallback = new RdDItemRace({ name: 'Humain', type: RdDItemRace.ITEM_TYPE })
    }
    return RdDItemRace.fallback
  }


  isMax(actor, code, value = undefined) {
    const path = RdDCarac.carac(code)?.path
    if (path == undefined) {
      // cas des caractéristiques dérivées, pas de max
      return false
    }
    if (value == undefined) {
      value = path ? foundry.utils.getProperty(actor, path) : 0
    }
    if (code == LIST_CARAC_PERSONNAGE.force.code) {
      return value >= this.getForceMax(actor)
    }
    const pathMax = path.replace(".value", ".max");
    const max = foundry.utils.getProperty(this, pathMax) ?? -1
    return (max > 0 && value >= max)
  }

  getValidTaille(taille) {
    const min = Math.max(this.system.carac.taille.min, 0)
    if (min > taille) {
      _warn("La Taille est inférieur au minimum racial")
      return min
    }
    const raceMax = this.system.carac.taille.max == undefined ? 15 + this.system.carac.taille.value : this.system.carac.taille.max
    const max = raceMax < 0 ? taille + 1 : raceMax
    if (max < taille) {
      _warn("La Taille est supérieure au maximum racial")
      return max
    }
    return taille
  }

  isForceValid(actor, value) {
    return value <= this.getForceMax(actor)
  }

  getForceMax(actor) {
    const terms = this.system.carac.force.limit.replaceAll(' ', '').split('+')
    return terms.map(
      it => {
        const term = Number.parseInt(it)
        if (Number.isInteger(term)) {
          return term
        }
        const path = RdDCarac.carac(it)?.path
        if (path) {
          return foundry.utils.getProperty(actor, path)
        }
        return 0
      }
    ).reduce(Misc.sum());
  }
}