import { RDD_CONFIG } from "./constants.js";
import { RdDItemArme } from "./item/arme.js";
import { RdDPossession } from "./combat/rdd-possession.js";
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";

const conditionsTactiques = [
  { key: '', label: '', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false },
  { key: 'normale', label: 'Attaque normale', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: true },
  { key: 'charge', label: 'Charge', dmg: 2, attaque: 4, parade: -4, esquive: false, isTactique: true },
  { key: 'feinte', label: 'Feinte', dmg: 1, attaque: 1, parade: 0, esquive: true, isTactique: true },
  { key: 'pret', label: 'prêt', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false },
  { key: 'demi', label: 'Demi-surprise', dmg: 1, attaque: 0, parade: 0, esquive: true, isTactique: false },
  { key: 'totale', label: 'Surprise totale', dmg: 10, attaque: 6, parade: 0, esquive: true, isTactique: false },
];

/* -------------------------------------------- */
export class RdDBonus {
  static get tactiques() {
    return conditionsTactiques.filter(it => it.isTactique)
  }
  /* -------------------------------------------- */
  static find(condition) {
    return conditionsTactiques.find(e => e.key == condition) || conditionsTactiques[0];
  }


  /* -------------------------------------------- */
  static isDefenseAttaqueFinesse(rollData) {
    if (rollData.isEmpoignade && rollData.rolled?.isPart) {
      return true
    }
    if (RdDPossession.isDefensePossession(rollData)) {
      return RdDPossession.isPossessionFinesse(rollData)
    }
    return rollData.attackerRoll?.particuliere == 'finesse';
  }

  /* -------------------------------------------- */
  static dmg(rollData, actor) {
    const diff = rollData.diffLibre;
    const dmgArme = RdDBonus.dmgArme(rollData.arme, rollData.arme?.system.dommagesReels)
    const forceRequise = rollData.arme ? RdDItemArme.valeurMain(rollData.arme.system.force ?? 0, RdDItemArme.getMainAttaque(rollData.competence)) : 0
    let dmg = {
      total: 0,
      dmgArme: dmgArme,
      diff: diff,
      dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(diff ?? 0) : 0,
      penetration: RdDBonus._peneration(rollData),
      dmgTactique: RdDBonus.dmgBonus(rollData.tactique),
      dmgParticuliere: RdDBonus._dmgParticuliere(rollData),
      dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris?.used),
      mortalite: RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite),
      dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme),
      dmgForceInsuffisante: Math.min(0, actor.getForce() - forceRequise)
    }
    dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante
    return dmg
  }

  static dmgRollV2(rollData, attaque) {
    const actor = rollData.active.actor
    const arme = attaque.arme
    const dmgArme = RdDBonus.dmgArme(arme, attaque.dommages)
    const dmg = {
      total: 0,
      dmgArme: dmgArme,
      penetration: arme?.system.penetration ?? 0,
      diff: attaque.diff,
      dmgTactique: attaque.tactique?.dmg ?? 0,
      dmgParticuliere: RdDBonus._dmgParticuliere(rollData),
      dmgSurprise: rollData.opponent?.surprise?.dmg ?? 0,
      mortalite: RdDBonus.mortalite(attaque.dmg?.mortalite, arme?.system.mortalite),
      dmgActor: RdDBonus.bonusDmg(actor, attaque.carac?.key, dmgArme, attaque.forceRequise),
      dmgForceInsuffisante: Math.min(0, actor.getForce() - (attaque.forceRequise ?? 0)),
      dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0
    }
    dmg.isEmpoignade = dmg.mortalite == RDD_CONFIG.encaissement.empoignade
    dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante + dmg.dmgDiffLibre
    return dmg
  }

  /* -------------------------------------------- */
  static description(condition) {
    return RdDBonus.find(condition).label
  }

  /* -------------------------------------------- */
  static dmgBonus(condition) {
    return RdDBonus.find(condition).dmg
  }

  /* -------------------------------------------- */
  static bonusAttaque(condition) {
    return RdDBonus.find(condition).attaque
  }

  /* -------------------------------------------- */
  static mortalite(mortaliteSelect, mortaliteArme) {
    return mortaliteSelect ?? mortaliteArme ?? RDD_CONFIG.encaissement.mortel
  }

  /* -------------------------------------------- */
  static dmgArme(arme, dommages) {
    if (arme) {
      let dmgBase = dommages ?? Number(arme.system.dommages ?? 0);
      //Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278)
      return dmgBase + Math.min(dmgBase, arme.system.magique ? arme.system.ecaille_efficacite : 0);
    }
    return 0;
  }

  /* -------------------------------------------- */
  static _peneration(rollData) {
    return parseInt(rollData.arme?.system.penetration ?? 0);
  }

  /* -------------------------------------------- */
  static bonusDmg(actor, categorie, dmgArme) {
    if (categorie == undefined) {
      return 0
    }
    const dmgActor = actor.getBonusDegat()
    switch (categorie) {
      case "(tir)": case "tir": return 0
      case "(lancer)": case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
    }
    return dmgActor;
  }

  /* -------------------------------------------- */
  static _dmgParticuliere(rollData) {
    return rollData.particuliere == 'force' ? 5 : 0;
  }

}