import { DialogItemVente } from "./dialog-item-vente.js";
import { Grammar } from "./grammar.js";
import { RdDHerbes } from "./rdd-herbes.js";
import { RdDUtility } from "./rdd-utility.js";

const typesObjetsEquipement = [
  "arme",
  "armure",
  "conteneur",
  "gemme",
  "herbe",
  "ingredient",
  "livre",
  "monnaie",
  "munition",
  "nourritureboisson",
  "objet",
  "potion",
]
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve"]
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
const typesObjetsEffet = ["possession", "poison", "maladie"]
const typesObjetsCompetence = ["competence", "compcreature"]
const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc
densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/ 
   */

export const defaultItemImg = {
  competence: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
  compcreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
  arme: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp",
  armure: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp",
  conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp",
  sort: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
  herbe: "systems/foundryvtt-reve-de-dragon/icons/botanique/Endorlotte.webp",
  ingredient: "systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp",
  livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp",
  potion: "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp",
  queue: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
  ombre: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
  souffle: "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp",
  tete: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp",
  meditation: "systems/foundryvtt-reve-de-dragon/icons/meditations_ecrits/meditation_alchimie.webp",
  recettealchimique: "systems/foundryvtt-reve-de-dragon/icons/competence_alchimie.webp",
  chant: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp",
  danse: "systems/foundryvtt-reve-de-dragon/icons/arts/danse_0.webp",
  jeu: "systems/foundryvtt-reve-de-dragon/icons/arts/jeux_petasse.webp",
  recettecuisine: "systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_1.webp",
  musique: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp",
  maladie: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/maladie.webp",
  poison: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp",
  oeuvre: "systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp",
  nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
  signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp",
  gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp",
  possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
  sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
}

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

  constructor(itemData, context) {
    if (!itemData.img) {
      itemData.img = defaultItemImg[itemData.type];
    }
    super(itemData, context);
  }

  static getTypesObjetsEquipement() {
    return typesObjetsEquipement
  }

  static getTypesOeuvres() {
    return typesObjetsOeuvres
  }

  isCompetence() {
    return typesObjetsCompetence.includes(this.type)
  }
  isEquipement() {
    return typesObjetsEquipement.includes(this.type)
  }
  isOeuvre() {
    return typesObjetsOeuvres.includes(this.type)
  }
  isDraconique() {
    return typesObjetsDraconiques.includes(this.type)
  }
  isEffet() {
    return typesObjetsEffet.includes(this.type)
  }
  isConnaissance() {
    return typesObjetsConnaissance.includes(this.type)
  }
  isConteneur() {
    return this.type == 'conteneur';
  }

  getItemGroup() {
    if (this.isEquipement()) return "equipement";
    if (this.isOeuvre()) return "oeuvre";
    if (this.isDraconique()) return "draconique";
    if (this.isConnaissance()) return "connaissance";
    if (this.isEffet()) return "effet";
    if (this.isCompetence()) return "competence";
    return "autres";
  }

  isConteneurNonVide() {
    return this.isConteneur() && (this.system.contenu?.length ?? 0) > 0;
  }

  isConteneurVide() {
    return this.isConteneur() && (this.system.contenu?.length ?? 0) == 0;
  }

  isVideOuNonConteneur() {
    return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0;
  }

  isAlcool() {
    return this.type == 'nourritureboisson' && this.system.boisson && this.system.alcoolise;
  }
  isHerbeAPotion() {
    return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos');
  }
  isPotion() {
    return this.type == 'potion';
  }
  isCristalAlchimique() {
    return this.type == 'objet' && Grammar.toLowerCaseNoAccent(this.name) == 'cristal alchimique' && this.system.quantite > 0;
  }

  isMagique() {
    return this.system.magique
  }

  getQuantite() {
    return Math.round(this.isConteneur() ? 1 : (this.system.quantite ?? 0))
  }

  getEncTotal() {
    return this.getEnc() * this.getQuantite();
  }  

  getEnc() {
    switch (this.type) {
      case 'herbe':
        return encBrin;
      case 'gemme':
        return encPepin * this.system.taille;
    }
    return Math.max(this.system.encombrement ?? 0, 0);
  }

  prixTotalDeniers() {
    return this.getQuantite() * this.valeurDeniers()
  }

  valeurDeniers() {
    return Math.max(Math.round(this.system.cout ? (this.system.cout * 100) : (this.system.valeur_deniers ?? 0)), 0) 
  }

  prepareDerivedData() {
    super.prepareDerivedData();
    if (this.isEquipement()) {
      this.system.encTotal = this.getEncTotal();
      if (this.isPotion()) {
        this.prepareDataPotion()
      }
      this.system.actionPrincipale = this.getActionPrincipale({ warnIfNot: false });
    }
  }

  prepareDataPotion() {
    const categorie = Grammar.toLowerCaseNoAccent(this.system.categorie);
    this.system.magique = categorie.includes('enchante');
    if (this.system.magique) {
      if (categorie.includes('soin') || categorie.includes('repos')) {
        // TODO: utiliser calculePointsRepos / calculePointsGuerison
        this.system.puissance = RdDHerbes.calculePuissancePotion(this);
      }
    }
  }

  getActionPrincipale(options = { warnIfNot: true }) {
    const warn = options.warnIfNot;
    switch (this.type) {
      case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
      case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn);
      case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn);
      case 'conteneur': return 'Ouvrir';
      case 'herbe':  return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
      case 'queue': case 'ombre': return this.system.refoulement>0 ? 'Refouler' : undefined;
    }
    return undefined;
  }

  _actionOrWarnQuantiteZero(actionName, warn){
    if ((this.system.quantite ?? 0) <= 0) {
      if (warn) {
        ui.notifications.warn(`Vous n'avez plus de ${this.name}.`);
      }
      return undefined;
    }
    else {
      return actionName;
    }
  }

  async diminuerQuantite(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) {
    if (options.diminuerQuantite == false) return;
    await this.quantiteIncDec(-nombre, options);
  }

  async quantiteIncDec(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) {
    const quantite = Number(this.system.quantite ?? -1);
    if (quantite >= 0) {
      const reste = Math.max(quantite + Number(nombre), 0);

      if (reste == 0) {
        if (options.supprimerSiZero) {
          ui.notifications.notify(`${this.name} supprimé de votre équipement`);
          await this.delete();
        }
        else {
          ui.notifications.notify(`Il ne vous reste plus de ${this.name}, vous pouvez le supprimer de votre équipement, ou trouver un moyen de vous en procurer.`);
          await this.update({ "system.quantite": 0 });
        }
      }
      else {
        await this.update({ "system.quantite": reste });
      }
    }
  }

  /* -------------------------------------------- */
  // détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité
  messageEquipementDifferent(other) {
    if (!other || !this.isEquipement()) return undefined;

    let message = undefined;
    if (this.system.quantite == undefined) {
      message = `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`;
    } 
    else if (this.type != other.type) {
      message = `Impossible de regrouper des ${this.type} avec des ${other.type}`;
    }
    else if (this.name != other.name) {
      message = `Impossible de regrouper ${this.name} avec ${other.name}`;
    }
    else {
      const differences = Object.entries(this.system)
        .filter(([key, value]) => !['quantite', 'cout'].includes(key) && value != other.system[key]);
      if (differences.length > 0) {
        message = `Impossible de regrouper les ${this.type} ${this.name}: `;
        for (const [key, value] of differences) {
          message += `<br>${key}: ${value} vs ${other.system[key]}`;
        }
      }
    }
    return message;
  }

  async proposerVente() {
    console.log(this);
    if (this.isConteneurNonVide()) {
      ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
      return;
    }
    await DialogItemVente.display(this, async (vente) =>  {
      vente["properties"] = this.getProprietes();
      if (vente.isOwned) {
        if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) {
          ui.notifications.warn(`Vous avez ${vente.quantiteMax} ${vente.item.name}, ce n'est pas suffisant pour vendre ${vente.quantiteNbLots} de ${vente.tailleLot}`)
          return;
        }
      }
      vente.jsondata = JSON.stringify(vente.item);
  
      console.log(vente);
      let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
      ChatMessage.create(RdDUtility.chatDataSetup(html));
    });
  }

  /* -------------------------------------------- */
  getProprietes() {
    return this[`_${this.type}ChatData`]();
  }

  /* -------------------------------------------- */
  async postItem(modeOverride) {
    console.log(this);
    let chatData = duplicate(this);
    const properties = this.getProprietes();
    chatData["properties"] = properties
    if (this.actor) {
      chatData.actor = { id: this.actor.id };
    }
    // JSON object for easy creation
    chatData.jsondata = JSON.stringify(
      {
        compendium: "postedItem",
        payload: chatData,
      });

    renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-item.html', chatData).then(html => {
      let chatOptions = RdDUtility.chatDataSetup(html, modeOverride);
      ChatMessage.create(chatOptions)
    });
  }

  static propertyIfDefined(name, val, condition = (it) => true) {
    return condition ? [`<b>${name}</b>: ${val}`] : [];
  }

  /* -------------------------------------------- */
  _objetChatData() {
    const tplData = this.system
    let properties = [].concat(
      RdDItem.propertyIfDefined('Résistance', tplData.resistance, tplData.resistance),
      RdDItem.propertyIfDefined('Qualité', tplData.qualite, tplData.qualite),
      RdDItem.propertyIfDefined('Encombrement', tplData.encombrement),
    );
    return properties;
  }

  /* -------------------------------------------- */
  _nourritureboissonChatData() {
    const tplData = this.system
    let properties = [].concat(
      RdDItem.propertyIfDefined('Sustentation', tplData.sust, tplData.sust > 0),
      RdDItem.propertyIfDefined('Désaltère', tplData.desaltere, tplData.boisson),
      RdDItem.propertyIfDefined('Force alcool', tplData.force, tplData.boisson && tplData.alcoolise),
      RdDItem.propertyIfDefined('Exotisme', tplData.exotisme, tplData.exotisme < 0),
      RdDItem.propertyIfDefined('Qualité', tplData.qualite, tplData.qualite),
      RdDItem.propertyIfDefined('Encombrement', tplData.encombrement),
    );
    return properties;
  }
  /* -------------------------------------------- */
  _armeChatData() {
    const tplData = this.system
    let properties = [
      `<b>Compétence</b>: ${tplData.competence}`,
      `<b>Dommages</b>: ${tplData.dommages}`,
      `<b>Force minimum</b>: ${tplData.force}`,
      `<b>Resistance</b>: ${tplData.resistance}`,
      `<b>Encombrement</b>: ${tplData.encombrement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _conteneurChatData() {
    const tplData = this.system
    let properties = [
      `<b>Capacité</b>: ${tplData.capacite} Enc.`,
      `<b>Encombrement</b>: ${tplData.encombrement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _munitionChatData() {
    const tplData = this.system
    let properties = [
      `<b>Encombrement</b>: ${tplData.encombrement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _armureChatData() {
    const tplData = this.system
    let properties = [
      `<b>Protection</b>: ${tplData.protection}`,
      `<b>Détérioration</b>: ${tplData.deterioration}`,
      `<b>Malus armure</b>: ${tplData.malus}`,
      `<b>Encombrement</b>: ${tplData.encombrement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _competenceChatData() {
    const tplData = this.system
    let properties = [
      `<b>Catégorie</b>: ${tplData.categorie}`,
      `<b>Niveau</b>: ${tplData.niveau}`,
      `<b>Caractéristique par défaut</b>: ${tplData.carac_defaut}`,
      `<b>XP</b>: ${tplData.xp}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _competencecreatureChatData() {
    const tplData = this.system
    let properties = [
      `<b>Catégorie</b>: ${tplData.categorie}`,
      `<b>Niveau</b>: ${tplData.niveau}`,
      `<b>Caractéristique</b>: ${tplData.carac_value}`,
      `<b>XP</b>: ${tplData.xp}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _sortChatData() {
    const tplData = this.system
    let properties = [
      `<b>Draconic</b>: ${tplData.draconic}`,
      `<b>Difficulté</b>: ${tplData.difficulte}`,
      `<b>Case TMR</b>: ${tplData.caseTMR}`,
      `<b>Points de Rêve</b>: ${tplData.ptreve}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _herbeChatData() {
    const tplData = this.system
    let properties = [
      `<b>Milieu</b>: ${tplData.milieu}`,
      `<b>Rareté</b>: ${tplData.rarete}`,
      `<b>Catégorie</b>: ${tplData.categorie}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _ingredientChatData() {
    const tplData = this.system
    let properties = [
      `<b>Milieu</b>: ${tplData.milieu}`,
      `<b>Rareté</b>: ${tplData.rarete}`,
      `<b>Catégorie</b>: ${tplData.categorie}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _tacheChatData() {
    const tplData = this.system
    let properties = [
      `<b>Caractéristique</b>: ${tplData.carac}`,
      `<b>Compétence</b>: ${tplData.competence}`,
      `<b>Périodicité</b>: ${tplData.periodicite}`,
      `<b>Fatigue</b>: ${tplData.fatigue}`,
      `<b>Difficulté</b>: ${tplData.difficulte}`
    ].concat([
      tplData.cacher_points_de_tache ? [] :`<b>Points de Tâche</b>: ${tplData.points_de_tache}`
    ]).concat([
      `<b>Points de Tâche atteints</b>: ${tplData.points_de_tache_courant}`]
    );
    return properties;
  }
  /* -------------------------------------------- */
  _livreChatData() {
    const tplData = this.system
    let properties = [
      `<b>Compétence</b>: ${tplData.competence}`,
      `<b>Auteur</b>: ${tplData.auteur}`,
      `<b>Difficulté</b>: ${tplData.difficulte}`,
      `<b>Points de Tâche</b>: ${tplData.points_de_tache}`,
      `<b>Encombrement</b>: ${tplData.encombrement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _potionChatData() {
    const tplData = this.system
    let properties = [
      `<b>Rareté</b>: ${tplData.rarete}`,
      `<b>Catégorie</b>: ${tplData.categorie}`,
      `<b>Encombrement</b>: ${tplData.encombrement}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _queueChatData() {
    const tplData = this.system
    let properties = [
      `<b>Refoulement</b>: ${tplData.refoulement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _ombreChatData() {
    const tplData = this.system
    let properties = [
      `<b>Refoulement</b>: ${tplData.refoulement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _souffleChatData() {
    const tplData = this.system
    let properties = [];
    return properties;
  }
  /* -------------------------------------------- */
  _teteChatData() {
    const tplData = this.system
    let properties = [];
    return properties;
  }
  /* -------------------------------------------- */
  _tarotChatData() {
    const tplData = this.system
    let properties = [
      `<b>Concept</b>: ${tplData.concept}`,
      `<b>Aspect</b>: ${tplData.aspect}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _nombreastralChatData() {
    const tplData = this.system
    let properties = [
      `<b>Valeur</b>: ${tplData.value}`,
      `<b>Jour</b>: ${tplData.jourlabel}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _monnaieChatData() {
    const tplData = this.system
    let properties = [
      `<b>Valeur en Deniers</b>: ${tplData.valeur_deniers}`,
      `<b>Encombrement</b>: ${tplData.encombrement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _meditationChatData() {
    const tplData = this.system
    let properties = [
      `<b>Thème</b>: ${tplData.theme}`,
      `<b>Compétence</b>: ${tplData.competence}`,
      `<b>Support</b>: ${tplData.support}`,
      `<b>Heure</b>: ${tplData.heure}`,
      `<b>Purification</b>: ${tplData.purification}`,
      `<b>Vêture</b>: ${tplData.veture}`,
      `<b>Comportement</b>: ${tplData.comportement}`,
      `<b>Case TMR</b>: ${tplData.tmr}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _casetmrChatData() {
    const tplData = this.system
    let properties = [
      `<b>Coordonnée</b>: ${tplData.coord}`,
      `<b>Spécificité</b>: ${tplData.specific}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _maladieChatData() {
    const tplData = this.system
    let properties
    if (tplData.identifie) {
      properties = [
        `<b>Malignité</b>: ${tplData.malignite}`,
        `<b>Périodicité</b>: ${tplData.periodicite}`,
        `<b>Dommages</b>: ${tplData.dommages}`
      ]
      if (tplData.remedesconnus) {
        properties.push(`<b>Remedes</b>: ${tplData.remedes}`)
      }
    } else {
      properties = [
        `<b>Inconnue</b>`]
    }
    return properties;
  }

  /* -------------------------------------------- */
  _poisonChatData() {
    return this._maladieChatData();
  }

  /* -------------------------------------------- */
  _gemmeChatData() {
    const tplData = this.system
    let properties = [
      `<b>Pureté</b>: ${tplData.purete}`,
      `<b>Taille</b>: ${tplData.taille}`,
      `<b>Inertie</b>: ${tplData.inertie}`,
      `<b>Enchantabilité</b>: ${tplData.enchantabilite}`,
      `<b>Prix</b>: ${tplData.cout}`,
    ]
    return properties;
  }


}
