/**
 * RdD system
 * Author: LeRatierBretonnien
 * Software License: GNU GPLv3
 */

/* -------------------------------------------- */

/* -------------------------------------------- */
// Import Modules
import { RdDActor } from "./actor.js";
import { RdDItemSheet } from "./item-sheet.js";
import { RdDActorSheet } from "./actor-sheet.js";
import { RdDActorCreatureSheet } from "./actor-creature-sheet.js";
import { RdDActorHumanoideSheet } from "./actor-humanoide-sheet.js";
import { RdDActorEntiteSheet } from "./actor-entite-sheet.js";
import { RdDUtility } from "./rdd-utility.js";
import { TMRUtility } from "./tmr-utility.js";
import { RdDCalendrier } from "./rdd-calendrier.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { RdDTokenHud } from "./rdd-token-hud.js";

/* -------------------------------------------- */
/*  Foundry VTT Initialization                  */
/* -------------------------------------------- */

/************************************************************************************/
const _patch_initiative = () => {
  Combat.prototype.rollInitiative = async function (
    ids,
    formula = undefined,
    messageOptions = {}
  ) {
    console.log(
      `${game.data.system.data.title} | Combat.rollInitiative()`,
      ids,
      formula,
      messageOptions
    );
    // Structure input data
    ids = typeof ids === "string" ? [ids] : ids;
    const currentId = this.combatant._id;
    // calculate initiative
    for ( let cId = 0; cId < ids.length; cId++) {
      const c = this.getCombatant( ids[cId] );
      //if (!c) return results;

      let rollFormula = formula; // Init per default
      if ( !rollFormula ) {
        let armeCombat, competence;
        if ( c.actor.data.type == 'creature' ||  c.actor.data.type == 'entite') {
          for (const competenceItem of c.actor.data.items) {
            if ( competenceItem.data.iscombat) {
              competence = duplicate(competenceItem);
            }
          }
          rollFormula =  "1d6+" + competence.data.niveau + "+" + Math.ceil(competence.data.carac_value / 2);
        } else {
          for (const item of c.actor.data.items) {
            if (item.type == "arme" && item.data.equipe) {
              armeCombat = duplicate(item);
            }
          }
          let compName = ( armeCombat == undefined ) ? "Corps à corps" : armeCombat.data.competence;
          competence = RdDUtility.findCompetence( c.actor.data.items, compName );   
          rollFormula =  "1d6+" + competence.data.niveau + "+" + Math.ceil(c.actor.data.data.carac[competence.data.defaut_carac].value/2);
        }
      }
      //console.log("Combatat", c);
      const roll = this._getInitiativeRoll(c, rollFormula);
      if ( roll.total <= 0 ) roll.total = 1;
      //console.log("Compute init for", armeCombat, competence, rollFormula, roll.total);      
      await this.updateEmbeddedEntity("Combatant",  { _id: c._id, initiative: roll.total });
      
      // Send a chat message
      let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode");
      let messageData = mergeObject(
        {
          speaker: {
            scene: canvas.scene._id,
            actor: c.actor ? c.actor._id : null,
            token: c.token._id,
            alias: c.token.name,
            sound: CONFIG.sounds.dice,
          },
          flavor: `${c.token.name} a fait son jet d'Initiative`,
        },
        messageOptions
      );
      roll.toMessage(messageData, { rollMode, create: true });
    }
    return this;
  };
}

/************************************************************************************/
Hooks.once("init", async function() {
  console.log(`Initializing Reve de Dragon System`);
  
  // preload handlebars templates
  RdDUtility.preloadHandlebarsTemplates();

  // Create useful storage space
  game.system.rdd = {
    rollDataHandler: {},
    TMRUtility: TMRUtility
    }
  game.settings.register("foundryvtt-reve-de-dragon", "accorder-entite-cauchemar", {
    name: "Accorder le rêve aux entités",
    hint: "A quel moment les personnages doivent accorder leur rêve aux entités de cauchemar",
    scope: "world",
    config: true,
    type: String,
    choices: {           // If choices are defined, the resulting setting will be a select menu
      "avant-attaque": "Avant l'attaque",
      "avant-defense": "Avant la défense",
      "avant-encaissement": "Avant l'encaissement",
    },
    default: "avant-encaissement"
  });

  // Create specific settings  
  // game.settings.register("foundryvtt-reve-de-dragon", "configuration", {
  //   name: "configuration",  
  //   scope: "world",
  //   config: false,
  //   type: Object
  // });
  game.settings.register("foundryvtt-reve-de-dragon", "dice-so-nice", {
    name: "Montrer les dés pour toutes les jets",
    hint: "Utilise Dice So Nice pour tous les jets de dés possibles. Décocher pour limiter à la table de résolution",
    scope: "client",
    config: true,
    default: false,
    type: Boolean
  });  
  //game.settings.get("<systemName>","<settingName>") to retrieve it and  game.settings.set("<systemName>","<settingName>", <newValue>)
  
	/**
	 * Set an initiative formula for the system
	 * @type {String}
	 */
	CONFIG.Combat.initiative = {
	  formula: "1d20",
    decimals: 2
  };
  
  game.socket.on("system.foundryvtt-reve-de-dragon", data => {
    RdDUtility.performSocketMesssage( data );
  });

	// Define custom Entity classes
  CONFIG.Actor.entityClass = RdDActor;
  CONFIG.RDD = { 
    resolutionTable       : RdDResolutionTable.resolutionTable,
    level_category        : RdDUtility.getLevelCategory(),
    carac_array           : RdDUtility.getCaracArray(),
    ajustementsConditions : RdDUtility.getAjustementsConditions(),
    difficultesLibres     : RdDUtility.getDifficultesLibres()
  }
  
  // Register sheet application classes
  Actors.unregisterSheet("core", ActorSheet);
  Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorSheet, {
     types: ["personnage"],
     makeDefault: true }
  );
  Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorCreatureSheet,  {
    types: ["creature"],
    makeDefault: true
  });
  Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorHumanoideSheet,  {
    types: ["humanoide"],
    makeDefault: true
  });
  Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorEntiteSheet,  {
    types: ["entite"],
    makeDefault: true
  });
  Items.unregisterSheet("core", ItemSheet);
  Items.registerSheet("foundryvtt-reve-de-dragon", RdDItemSheet, {makeDefault: true});

  // Handlebar function pour container
  Handlebars.registerHelper('buildConteneur', (objet) => { return RdDUtility.buildConteneur(objet); });

  // Patch the initiative formula
  _patch_initiative();
});

/* -------------------------------------------- */
function messageDeBienvenue(){
  game.messages
    .filter(it => it.user._id == game.user._id && it.data.content.match(/^Bienvenu(e)? dans le Rêve des Dragons/))
    .forEach(it => it.delete());
  ChatMessage.create( {
    user: game.user._id,
    whisper:  [game.user._id],
    content : "Bienvenue dans le Rêve des Dragons !<br> " +
      "Vous trouverez quelques informations pour démarrer dans ce document : @Compendium[foundryvtt-reve-de-dragon.rappel-des-regles.7uGrUHGdPu0EmIu2]{Documentation MJ/Joueurs}" }
    );
}

/* -------------------------------------------- */
Hooks.once("renderApplication", () => {
  messageDeBienvenue();
});

/* -------------------------------------------- */
/*  Foundry VTT Initialization                  */
/* -------------------------------------------- */
Hooks.once("ready", function() {
  /* Affiche le calendrier */
  //let calendrier = new RdDCalendrier();
  //let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html";
  //let templateData = {};
  /* DISABLEDrenderTemplate(templatePath, templateData).then(html => {
    calendrier.render(true);
  } ); */
  // Avertissement si joueur sans personnage
  if ( !game.user.isGM && game.user.character == undefined) {
    ui.notifications.info( "Attention ! Vous n'êtes connecté à aucun personnage !" );
    ChatMessage.create( { content:"<b>ATTENTION</b> Le joueur " + game.user.name + " n'est connecté à aucun personnage !", 
            user: game.user._id } );
            //whisper:  [ ChatMessage.getWhisperRecipients("GM") ] } );
  }

  // Integration du TokenHUD
  Hooks.on('renderTokenHUD', (app, html, data) => { RdDTokenHud.addTokenHudExtensions(app, html, data) });
});

/* -------------------------------------------- */
/* Abandonné pour l'instant
Hooks.on("preCreateToken", (scene, tokenData, options) => {
  let actor = game.actors.get( tokenData.actorId )
  if (actor) {
    let tokenSize = actor.data.data.carac.taille.value / 10;
    tokenData.width  = tokenSize;
    tokenData.height = tokenSize;
  }
  console.log("PRECREATE:", scene, tokenData, options);
});*/

/* -------------------------------------------- */
/*  Foundry VTT Initialization                  */
/* -------------------------------------------- */
Hooks.on("chatMessage", (html, content, msg) => {
  let regExp;
  regExp = /(\S+)/g;
  let commands = content.match(regExp);

  return RdDUtility.processChatCommand( commands, content, msg );
} );

/* -------------------------------------------- */
Hooks.on("getCombatTrackerEntryContext", (html, options) => {
  RdDUtility.pushInitiativeOptions( html, options );
})