import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
import { Misc } from "./misc.js";
import { RdDCombatManager } from "./rdd-combat.js";

const nomCategorieParade = {
  "sans-armes": "Sans arme / armes naturelles",
  "hast": "Armes d'hast",
  "batons": "Bâtons",
  "boucliers": "Boucliers",
  "dagues": "Dagues",
  "epees-courtes": "Epées courtes",
  "epees-longues": "Epées longues",
  "epees-lourdes": "Epées lourdes",
  "haches": "Haches",
  "lances": "Lances",
}

/* -------------------------------------------- */
export class RdDItemArme extends Item {

  static isArme(itemData) {
    itemData = Misc.data(itemData);
    return (itemData.type == 'competencecreature' && itemData.data.iscombat) || itemData.type == 'arme';
  }

  /* -------------------------------------------- */
  static getArmeData(armeData) {
    armeData = Misc.data(armeData);
    switch (armeData ? armeData.type : '') {
      case 'arme': return armeData;
      case 'competencecreature':
        return RdDItemCompetenceCreature.toArme(armeData);
    }
    return RdDItemArme.mainsNues();
  }

  static computeNiveauArmes(armes, competences) {
    for (const arme of armes) {
      arme.data.niveau = RdDItemArme.niveauCompetenceArme(arme, competences);
    }
  }

  static niveauCompetenceArme(arme, competences) {
    const compArme = competences.find(it => it.name == arme.data.competence);
    return compArme?.data.niveau ?? -8;
  }

  /* -------------------------------------------- */
  static getNomCategorieParade(arme) {
    const categorie = arme?.data ? RdDItemArme.getCategorieParade(arme) : arme;
    return nomCategorieParade[categorie];
  }

  /* -------------------------------------------- */
  static needArmeResist(armeAttaque, armeParade) {
    if (!armeAttaque || !armeParade) {
      return false;
    }
    // Epées parant une arme de bois (cf. page 115 ), une résistance est nécessaire
    let attCategory = RdDItemArme.getCategorieParade(armeAttaque);
    let defCategory = RdDItemArme.getCategorieParade(armeParade);

    return attCategory.match(/epees-/) && defCategory.match(/(haches|lances)/);
  }

  /* -------------------------------------------- */
  static getCategorieParade(armeData) {
    armeData = Misc.data(armeData);
    if (armeData.data.categorie_parade) {
      return armeData.data.categorie_parade;
    }
    // pour compatibilité avec des personnages existants
    if (armeData.type == 'competencecreature' || armeData.data.categorie == 'creature') {
      return armeData.data.categorie_parade || (armeData.data.isparade ? 'sans-armes' : '');
    }
    if (!armeData.type.match(/arme|competencecreature/)) {
      return '';
    }
    if (armeData.data.competence == undefined) {
      return 'competencecreature';
    }
    let compname = armeData.data.competence.toLowerCase();
    if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) return '';

    if (compname.match('hache')) return 'haches';
    if (compname.match('hast')) return 'hast';
    if (compname.match('lance')) return 'lances';
    if (compname.match('bouclier')) return 'boucliers';
    if (compname.match('masse')) return 'masses';
    if (compname.match('epée') || compname.match('épée')) {
      if (armeData.name.toLowerCase().match(/(gnome)/))
        return 'epees-courtes';
      if (armeData.name.toLowerCase().match(/((e|é)pée dragone|esparlongue|demi-dragonne)/))
        return 'epees-longues';
      return 'epees-lourdes';
    }
    if (compname.match('dague')) {
      return 'dagues';
    }
    return 'sans-armes';
  }

  /* -------------------------------------------- */
  static needParadeSignificative(armeAttaque, armeParade) {
    if (!armeAttaque || !armeParade) {
      return false;
    }
    // categories d'armes à la parade (cf. page 115 )
    let attCategory = RdDItemArme.getCategorieParade(armeAttaque);
    let defCategory = RdDItemArme.getCategorieParade(armeParade);
    // bouclier et mêmes catégorie: peuvent se parer sans difficulté
    if (defCategory == 'boucliers') {
      return false;
    }
    // Parer avec une hache ou une arme d’hast exige toujours une signi$cative
    if (defCategory.match(/(hast|haches)/)) {
      return true;
    }
    if (defCategory == attCategory) {
      return false;
    }
    // les épées se parent entre elles
    if (defCategory.match(/epees-/) && attCategory.match(/epees-/)) {
      return false;
    }
    // l'épée gnome pare la dague
    if (defCategory == 'epees-courtes' && attCategory == 'dagues') {
      return false;
    }
    // la dague pare les épées courtes et légères
    if (defCategory == 'dagues' && attCategory.match(/epees-(courtes|legeres)/)) {
      return false;
    }
    return true;
  }

  /* -------------------------------------------- */
  static armeUneOuDeuxMains(armeData, aUneMain) {
    armeData = Misc.data(armeData);
    if (armeData) {
      armeData.data.unemain = armeData.data.unemain || !armeData.data.deuxmains;
      const uneOuDeuxMains = armeData.data.unemain && armeData.data.deuxmains;
      const containsSlash = !Number.isInteger(armeData.data.dommages) && armeData.data.dommages.includes("/");
      if (containsSlash) { // Sanity check
        armeData = duplicate(armeData);

        const tableauDegats = armeData.data.dommages.split("/");
        if (aUneMain)
          armeData.data.dommagesReels = Number(tableauDegats[0]);
        else // 2 mains
          armeData.data.dommagesReels = Number(tableauDegats[1]);
      }
      else {
        armeData.data.dommagesReels = Number(armeData.data.dommages);
      }

      if (uneOuDeuxMains != containsSlash) {
        ui.notifications.info("Les dommages de l'arme à 1/2 mains " + armeData.name + " ne sont pas corrects (ie sous la forme X/Y)");
      }
    }
    return armeData;
  }

  static isArmeUtilisable(itemData) {
    itemData = Misc.data(itemData);
    return itemData.type == 'arme' && itemData.data.equipe && (itemData.data.resistance > 0 || itemData.data.portee_courte > 0);
  }

  static ajoutCorpsACorps(armes, competences, carac) {
    let corpsACorps = competences.find(it => it.name == 'Corps à corps') ?? { data: { niveau: -6 } };
    let init = RdDCombatManager.calculInitiative(corpsACorps.data.niveau, carac['melee'].value);
    armes.push(RdDItemArme.mainsNues({ niveau: corpsACorps.data.niveau, initiative: init }));
  }

  static mainsNues(actorData = {}) {
    const mainsNues = {
      name: 'Mains nues',
      data: {
        equipe: true,
        rapide: true,
        force: 0,
        dommages: 0,
        dommagesReels: 0,
        mortalite: 'non-mortel',
        competence: 'Corps à corps',
        categorie_parade: 'sans-armes'
      }
    };
    if (actorData) {
      mergeObject(mainsNues.data, actorData, { overwrite: false });
    }
    return mainsNues
  }
}