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

const typesObjetsEquipement = ["objet", "arme", "armure", "gemme", "conteneur", "herbe", "ingredient", "livre", "potion", "munition", "nourritureboisson", "monnaie"];
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"];
const encBrin = 0.00005;// un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc

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"
}

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

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

  static getTypeObjetsEquipement() {
    return typesObjetsEquipement;
  }

  static getTypesOeuvres() {
    return typesObjetsOeuvres;
  }

  isCompetence() {
    return Misc.data(this).type == 'competence';
  }

  isConteneur() {
    return Misc.data(this).type == 'conteneur';
  }

  isVide() {
    return this.isConteneur() && (Misc.templateData(this).contenu ?? []).length == 0;
  }

  isAlcool() {
    const itemData = Misc.data(this);
    return itemData.type == 'nourritureboisson' && itemData.data.boisson && itemData.data.alcoolise;
  }

  isPotion() {
    return Misc.data(this).type == 'potion';
  }

  isEquipement() {
    return RdDItem.getTypeObjetsEquipement().includes(Misc.data(this).type);
  }

  isCristalAlchimique() {
    const itemData = Misc.data(this);
    return itemData.type == 'objet' && Grammar.toLowerCaseNoAccent(itemData.name) == 'cristal alchimique' && itemData.data.quantite > 0;
  }

  isMagique() {
    return Misc.templateData(this).magique;
  }

  getEncTotal() {
    const itemData = Misc.data(this);
    return Number(itemData.data.encombrement ?? 0) * Number(itemData.data.quantite ?? 1);
  }
  getEnc() {
    const itemData = Misc.data(this);
    switch (itemData.type) {
      case 'herbe':
        return encBrin;
    }
    return itemData.data.encombrement ?? 0;
  }

  prepareDerivedData() {
    super.prepareDerivedData();
    if (this.isEquipement(this)) {
      this._calculsEquipement();
    }
    if (this.isPotion()) {
      this.prepareDataPotion()
    }
    const itemData = Misc.data(this);
    itemData.data.actionPrincipale = this.getActionPrincipale({ warnIfNot: false });
  }

  prepareDataPotion() {
    const tplData = Misc.templateData(this);
    const categorie = Grammar.toLowerCaseNoAccent(tplData.categorie);
    tplData.magique = categorie.includes('enchante');
    if (tplData.magique) {
      if (categorie.includes('soin') || categorie.includes('repos')) {
        tplData.puissance = tplData.herbebonus * tplData.pr;
      }
    }
  }

  _calculsEquipement() {
    const tplData = Misc.templateData(this);
    const quantite = this.isConteneur() ? 1 : (tplData.quantite ?? 0);
    const enc = this.getEnc();
    if (enc != undefined) {
      tplData.encTotal = Math.max(enc, 0) * quantite;
    }
    if (tplData.cout != undefined) {
      tplData.prixTotal = Math.max(tplData.cout, 0) * quantite;
    }
  }

  getActionPrincipale(options = { warnIfNot: true }) {
    const itemData = Misc.data(this);
    if ((itemData.data.quantite ?? 0) <= 0) {
      if (options.warnIfNot) {
        ui.notifications.warn(`Vous n'avez plus de ${itemData.name}.`);
      }
      return undefined;
    }
    switch (itemData.type) {
      case 'nourritureboisson': return itemData.data.boisson ? 'Boire' : 'Manger';
      case 'potion': return 'Boire';
      case 'livre': return 'Lire';
    }
    if (options.warnIfNot) {
      ui.notifications.warn(`Impossible d'utilise un ${itemData.name}, aucune action associée définie.`);
    }

    return undefined;
  }

  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 itemData = Misc.data(this);
    const quantite = Number(itemData.data.quantite ?? -1);
    if (quantite >= 0) {
      const reste = Math.max(quantite + Number(nombre), 0);

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

  /* -------------------------------------------- */
  // détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité
  isEquipementSimilaire(other) {
    const itemData = Misc.data(this);
    const otherData = Misc.data(other);
    const tplData = Misc.templateData(this);
    const otherTplData = Misc.templateData(other);
    if (!this.isEquipement()) return false;
    if (itemData.type != otherData.type) return false;
    if (itemData.name != otherData.name) return false;
    if (tplData.quantite == undefined) return false;

    const differences = Object.entries(tplData).filter(([key, value]) => !['quantite', 'encTotal', 'prixTotal', 'cout'].includes(key))
      .filter(([key, value]) => value != otherTplData[key]);
    if (differences.length > 0) {
      let message = `Impossible de regrouper les ${itemData.type} ${itemData.name}: `;
      for (const [key, value] of differences){
        message += `<br>${key}: ${value} vs ${otherTplData[key]}`;
      }
      ui.notifications.info(message)
      return false;
    }
    return true;
  }

  async proposerVente() {
    console.log(this);
    const dialog = await DialogItemVente.create(this, (vente) => this._onProposerVente(vente))
    dialog.render(true);
  }

  async _onProposerVente(venteData) {
    venteData["properties"] = this.getProprietes();
    if (venteData.isOwned) {
      if (venteData.quantiteNbLots * venteData.tailleLot > venteData.quantiteMax) {
        ui.notifications.warn(`Vous avez ${venteData.quantiteMax} ${venteData.item.name}, ce n'est pas suffisant pour vendre ${venteData.quantiteNbLots} de ${venteData.tailleLot}`)
        return;
      }
    }
    venteData.jsondata = JSON.stringify(venteData.item);

    console.log(venteData);
    let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', venteData);
    ChatMessage.create(RdDUtility.chatDataSetup(html));
  }

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

  /* -------------------------------------------- */
  async postItem( modeOverride ) {
    console.log(this);
    let chatData = duplicate(Misc.data(this));
    const properties = this.getProprietes();
    chatData["properties"] = properties
    if (this.actor) {
      chatData.actor = { id: this.actor.id };
    }
    //Check if the posted item should have availability/pay buttons
    chatData.hasPrice = "cout" in chatData.data;
    chatData.data.cout_deniers = 0;

    let dialogResult = [-1, -1]; // dialogResult[0] = quantité, dialogResult[1] = prix
    if (chatData.hasPrice) {
      chatData.data.cout_deniers = Math.floor(chatData.data.cout * 100);
      dialogResult = await new Promise((resolve, reject) => {
        new Dialog({
          content:
            `<p>Modifier la quantité?</p>
          <div class="form-group">
            <label> Quantité</label>
            <input name="quantity" type="text" value="1"/>
          </div>
          <p>Modifier la prix?</p>
          <div class="form-group">
            <label>Prix en Sols</label>
            <input name="price" type="text" value="${chatData.data.cout}"/>
          </div>
          `,
          title: "Quantité & Prix",
          buttons: {
            post: {
              label: "Soumettre",
              callback: (dlg) => {
                resolve([Number(dlg.find('[name="quantity"]').val()), Number(dlg.find('[name="price"]').val())])
              }
            },
          }
        }).render(true)
      })
    }

    let quantiteEnvoi = this.isOwned ? Math.min(dialogResult[0], chatData.data.quantite) : dialogResult[0];
    const prixTotal = dialogResult[1];
    if (quantiteEnvoi > 0) {
      if (this.isOwned) {
        if (chatData.data.quantite == 0) {
          quantiteEnvoi = -1
        }
        else if (quantiteEnvoi > chatData.data.quantite) {
          quantiteEnvoi = chatData.data.quantite;
          ui.notifications.notify(`Impossible de poster plus que ce que vous avez. La quantité à été réduite à ${quantiteEnvoi}.`)
        }
        if (quantiteEnvoi > 0) {
          this.diminuerQuantite(quantiteEnvoi);
        }
      }
    }

    if (chatData.hasPrice) {
      if (quantiteEnvoi > 0)
        chatData.postQuantity = Number(quantiteEnvoi);
      if (prixTotal >= 0) {
        chatData.postPrice = prixTotal;
        chatData.data.cout_deniers = Math.floor(prixTotal * 100); // Mise à jour cout en deniers
      }
      chatData.finalPrice = Number(chatData.postPrice) * Number(chatData.postQuantity);
      chatData.data.cout_deniers_total = chatData.data.cout_deniers * Number(chatData.postQuantity);
      chatData.data.quantite = chatData.postQuantity;
      console.log("POST : ", chatData.finalPrice, chatData.data.cout_deniers_total, chatData.postQuantity);
    }

    // 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 = Misc.templateData(this);
    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 = Misc.templateData(this);
    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 = Misc.templateData(this);
    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 = Misc.templateData(this);
    let properties = [
      `<b>Capacité</b>: ${tplData.capacite} Enc.`,
      `<b>Encombrement</b>: ${tplData.encombrement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _munitionChatData() {
    const tplData = Misc.templateData(this);
    let properties = [
      `<b>Encombrement</b>: ${tplData.encombrement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _armureChatData() {
    const tplData = Misc.templateData(this);
    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 = Misc.templateData(this);
    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 = Misc.templateData(this);
    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 = Misc.templateData(this);
    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 = Misc.templateData(this);
    let properties = [
      `<b>Milieu</b>: ${tplData.milieu}`,
      `<b>Rareté</b>: ${tplData.rarete}`,
      `<b>Catégorie</b>: ${tplData.categorie}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _ingredientChatData() {
    const tplData = Misc.templateData(this);
    let properties = [
      `<b>Milieu</b>: ${tplData.milieu}`,
      `<b>Rareté</b>: ${tplData.rarete}`,
      `<b>Catégorie</b>: ${tplData.categorie}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _tacheChatData() {
    const tplData = Misc.templateData(this);
    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}`,
      `<b>Points de Tâche</b>: ${tplData.points_de_tache}`,
      `<b>Points de Tâche atteints</b>: ${tplData.points_de_tache_courant}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _livreChatData() {
    const tplData = Misc.templateData(this);
    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 = Misc.templateData(this);
    let properties = [
      `<b>Rareté</b>: ${tplData.rarete}`,
      `<b>Catégorie</b>: ${tplData.categorie}`,
      `<b>Encombrement</b>: ${tplData.encombrement}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _queueChatData() {
    const tplData = Misc.templateData(this);
    let properties = [
      `<b>Refoulement</b>: ${tplData.refoulement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _ombreChatData() {
    const tplData = Misc.templateData(this);
    let properties = [
      `<b>Refoulement</b>: ${tplData.refoulement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _souffleChatData() {
    const tplData = Misc.templateData(this);
    let properties = [];
    return properties;
  }
  /* -------------------------------------------- */
  _teteChatData() {
    const tplData = Misc.templateData(this);
    let properties = [];
    return properties;
  }
  /* -------------------------------------------- */
  _tarotChatData() {
    const tplData = Misc.templateData(this);
    let properties = [
      `<b>Concept</b>: ${tplData.concept}`,
      `<b>Aspect</b>: ${tplData.aspect}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _nombreastralChatData() {
    const tplData = Misc.templateData(this);
    let properties = [
      `<b>Valeur</b>: ${tplData.value}`,
      `<b>Jour</b>: ${tplData.jourlabel}`,
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _monnaieChatData() {
    const tplData = Misc.templateData(this);
    let properties = [
      `<b>Valeur en Deniers</b>: ${tplData.valeur_deniers}`,
      `<b>Encombrement</b>: ${tplData.encombrement}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _meditationChatData() {
    const tplData = Misc.templateData(this);
    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 = Misc.templateData(this);
    let properties = [
      `<b>Coordonnée</b>: ${tplData.coord}`,
      `<b>Spécificité</b>: ${tplData.specific}`
    ]
    return properties;
  }
  /* -------------------------------------------- */
  _maladieChatData() {
    const tplData = Misc.templateData(this);
    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 = Misc.templateData(this);
    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;
  }


}
