/* -------------------------------------------- */
import { PegasusUtility } from "./pegasus-utility.js";
import { PegasusRollDialog } from "./pegasus-roll-dialog.js";

/* -------------------------------------------- */
const coverBonusTable = { "nocover": 0, "lightcover": 2, "heavycover": 4, "entrenchedcover": 6};

/* -------------------------------------------- */
/* -------------------------------------------- */
/**
 * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
 * @extends {Actor}
 */
export class PegasusActor extends Actor {

  /* -------------------------------------------- */
  /**
   * Override the create() function to provide additional SoS functionality.
   *
   * This overrided create() function adds initial items 
   * Namely: Basic skills, money, 
   *
   * @param {Object} data        Barebones actor data which this function adds onto.
   * @param {Object} options     (Unused) Additional options which customize the creation workflow.
   *
   */

  static async create(data, options) {

    // Case of compendium global import
    if (data instanceof Array) {
      return super.create(data, options);
    }
    // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
    if (data.items) {
      let actor = super.create(data, options);
      return actor;
    }

    if ( data.type == 'character') {
      const skills = await PegasusUtility.loadCompendium("fvtt-weapons-of-the-gods.skills");
      data.items = skills.map(i => i.toObject());
    }
    if ( data.type == 'npc') {
    }

    return super.create(data, options);
  }
    
  /* -------------------------------------------- */
  prepareBaseData() {
  }

  /* -------------------------------------------- */
  async prepareData() {
    super.prepareData();
  }

  /* -------------------------------------------- */
  prepareDerivedData() {

    if (this.type == 'character') {
      let h = 0;
      let updates = [];
      
      for (let key in this.data.data.statistics) {
        let attr = this.data.data.statistics[key];
      }
      /*if ( h != this.data.data.secondary.health.max) {
        this.data.data.secondary.health.max = h;
        updates.push( {'data.secondary.health.max': h} );
      }*/
      if ( updates.length > 0 ) {
        this.update( updates );
      }
      this.computeNRGHealth();
    }

    super.prepareDerivedData();
  }

  /* -------------------------------------------- */
  _preUpdate(changed, options, user) {

    super._preUpdate(changed, options, user);
  }
  /* -------------------------------------------- */
  getActivePerks() {
    let perks = this.data.items.filter( item => item.type == 'perk' && item.data.data.active);
    return perks;
  }  
  /* -------------------------------------------- */
  getAbilities() {
    let ab = this.data.items.filter( item => item.type == 'ability');
    return ab;
  }
  /* -------------------------------------------- */
  getPerks() {
    let comp = this.data.items.filter( item => item.type == 'perk');
    return comp;
  }
  /* -------------------------------------------- */
  getEffects() {
    let comp = this.data.items.filter( item => item.type == 'effect');
    return comp;
  }
  /* -------------------------------------------- */
  getPowers() {
    let comp = this.data.items.filter( item => item.type == 'power');
    return comp;
  }
  /* -------------------------------------------- */
  getArmors() {
    let comp = this.data.items.filter( item => item.type == 'armor');
    return comp;
  }
  /* -------------------------------------------- */
  getShields() {
    let comp = this.data.items.filter( item => item.type == 'shield');
    return comp;
  } 
  getRace() {
    let race = this.data.items.filter( item => item.type == 'race');
    return race[0]?? [];
  }
  getRole() {
    let role = this.data.items.filter( item => item.type == 'role');
    return role[0]?? [];
  }
  
  /* -------------------------------------------- */
  checkAndPrepareWeapon(item) {
    let types=[];
    let specs=[];
    let stats=[];
    item.data.specs = specs;
    item.data.stats = stats;
    item.data.typeText = types.join('/');
  }

  /* -------------------------------------------- */
  checkAndPrepareWeapons(weapons) {
    for ( let item of weapons) {
      this.checkAndPrepareWeapon(item);
    }
    return weapons;
  }

  /* -------------------------------------------- */
  getWeapons() {
    let comp = duplicate(this.data.items.filter( item => item.type == 'weapon' ) || []);
    return comp;
  }
  /* -------------------------------------------- */
  getItemById( id) {
    console.log("Search", id)
    let item = this.data.items.find( item => item.id == id);
    if (item ) {
      item = duplicate(item)
      if (item.type == 'specialisation') {
        item.data.dice = PegasusUtility.getDiceFromLevel(item.data.level);
      }
    }
    return item; 
  }

  /* -------------------------------------------- */
  getSpecs() {
    let comp = duplicate(this.data.items.filter( item => item.type == 'specialisation') || []);
    for (let c of comp) {
      c.data.dice = PegasusUtility.getDiceFromLevel(c.data.level);
    }
    return comp;
  }
  /* -------------------------------------------- */
  getRelevantSpec( statKey ) {
    let comp = duplicate(this.data.items.filter( item => item.type == 'specialisation' && item.data.data.statistic == statKey) || []);
    for (let c of comp) {
      c.data.dice = PegasusUtility.getDiceFromLevel(c.data.level);
    }
    return comp;
  }
  
  /* -------------------------------------------- */
  async activatePerk(perkId ) {
    let item = this.data.items.find( item => item.id == perkId );
    if (item && item.data.data) {
      let update = { _id: item.id, "data.active": !item.data.data.active };
      await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
    }
  }

  /* -------------------------------------------- */
  async equipItem(itemId ) {
    let item = this.data.items.find( item => item.id == itemId );
    if (item && item.data.data) {
      let update = { _id: item.id, "data.equipped": !item.data.data.equipped };
      await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
    }
  }

  /* -------------------------------------------- */
  compareName( a, b) {
    if ( a.name < b.name ) {
      return -1;
    }
    if ( a.name > b.name ) {
      return 1;
    }
    return 0;
  }

  /* ------------------------------------------- */
  getEquipments() {
    return this.data.items.filter( item => item.type == 'shield' || item.type == 'armor' || item.type == "weapon" || item.type == "equipment");
  }
  
  /* -------------------------------------------- */
  getActiveEffects(matching = it => true) {
    let array = Array.from(this.getEmbeddedCollection("ActiveEffect").values());
    return Array.from(this.getEmbeddedCollection("ActiveEffect").values()).filter(it => matching(it));
  }
  /* -------------------------------------------- */
  getEffectByLabel(label) {
    return this.getActiveEffects().find(it => it.data.label == label);
  }
  /* -------------------------------------------- */
  getEffectById(id) {
    return this.getActiveEffects().find(it => it.id == id);
  }

  /* -------------------------------------------- */
  getAttribute( attrKey ) {
    return this.data.data.attributes[attrKey];
  }
  /* -------------------------------------------- */

  async equipGear( equipmentId ) {    
    let item = this.data.items.find( item => item.id == equipmentId );
    if (item && item.data.data) {
      let update = { _id: item.id, "data.equipped": !item.data.data.equipped };
      await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
    }
  }
  /* -------------------------------------------- */
  getInitiativeScore( )  {
    if ( this.type == 'character') {
      // TODO
    } 
    return 0.0;
  }

  /* -------------------------------------------- */
  getArmorModifier( ) {
    let armors = this.getArmors();
    let modifier = 0;
    for (let armor of armors) {
      if (armor.data.data.equipped) {
        if (armor.data.data.type == 'light') modifier += 5;
        if (armor.data.data.type == 'medium') modifier += 10;
        if (armor.data.data.type == 'heavy') modifier += 15;
      }
    }
    return modifier;
  }

  /* -------------------------------------------- */
  async applyDamageLoss( damage) {
    let chatData = {
      user: game.user.id,
      alias : this.name,
      rollMode: game.settings.get("core", "rollMode"),
      whisper: [game.user.id].concat( ChatMessage.getWhisperRecipients('GM') ),
    };      
    //console.log("Apply damage chat", chatData );

    if (damage > 0 ) {
      let health = duplicate(this.data.data.secondary.health);
      health.value -= damage;
      if (health.value < 0 ) health.value = 0;
      this.update( { "data.secondary.health.value": health.value});
      chatData.content = `${this.name} looses ${damage} health. New health value is : ${health.value}`    ;
    } else {
      chatData.content = `No health loss for ${this.name} !`;    
    }
    await ChatMessage.create( chatData );
  }


  /* -------------------------------------------- */
  processNoDefense( attackRollData) {
    let defenseRollData = {
      mode : "nodefense",
      finalScore: 0,
      defenderName:  this.name,
      attackerName:  attackRollData.alias,
      armorModifier: this.getArmorModifier(),
      actorId: this.id,
      alias: this.name,
      result: 0,

    }
    this.syncRoll( defenseRollData );
    this.processDefenseResult(defenseRollData, attackRollData);     
  }

  /* -------------------------------------------- */
  async processApplyDamage(defenseRollData, attackRollData) { // Processed by the defender actor
    if ( attackRollData && attackRollData ) {
      let result = attackRollData.finalScore;
      defenseRollData.damageDices = WotGUtility.getDamageDice( result );
      defenseRollData.damageRoll = await this.rollDamage(defenseRollData);
      chatData.damages = true;
      chatData.damageDices = defenseRollData.damageDices;

      WotGUtility.createChatWithRollMode( this.name, {
        content: await renderTemplate(`systems/fvtt-weapons-of-the-gods/templates/chat-opposed-damages.html`, chatData)
      });
  }
  }

  /* -------------------------------------------- */
  async processDefenseResult(defenseRollData, attackRollData) { // Processed by the defenser

    if ( defenseRollData && attackRollData) {

      let result = attackRollData.finalScore - defenseRollData.finalScore;
      defenseRollData.defenderName =  this.name,
      defenseRollData.attackerName =  attackRollData.alias
      defenseRollData.result=  result
      defenseRollData.damages = false
      defenseRollData.damageDices = 0;

      if ( result > 0 ) {
        defenseRollData.damageDices = WotGUtility.getDamageDice( result );
        defenseRollData.damageRoll = await this.rollDamage(defenseRollData, attackRollData);
        defenseRollData.damages = true;
        defenseRollData.finalDamage = defenseRollData.damageRoll.total;
        WotGUtility.updateRollData( defenseRollData);
        console.log("DAMAGE ROLL OBJECT", defenseRollData);
        WotGUtility.createChatWithRollMode( this.name, {
          content: await renderTemplate(`systems/fvtt-weapons-of-the-gods/templates/chat-opposed-damage.html`, defenseRollData)
        });
      } else {
        WotGUtility.updateRollData( defenseRollData );
        WotGUtility.createChatWithRollMode( this.name, {
          content: await renderTemplate(`systems/fvtt-weapons-of-the-gods/templates/chat-opposed-fail.html`, defenseRollData)
        });
      }
    }
  }

  /* -------------------------------------------- */
  async rollDamage( defenseRollData, attackRollData ) {
    let weaponDamage = 0;
    if (attackRollData.weapon?.data?.damage) {
      weaponDamage = Number(attackRollData.weapon.data.damage);
    }
    let formula = defenseRollData.damageDices+"d10+"+defenseRollData.armorModifier + "+" + weaponDamage;
    console.log("ROLL : ", formula);
    let myRoll = new Roll(formula).roll( { async: false} );
    await WotGUtility.showDiceSoNice(myRoll, game.settings.get("core", "rollMode") );
    return myRoll;
  }

  /* -------------------------------------------- */
  getSubActors() {
    let subActors = [];
    for (let id of this.data.data.subactors) {
      subActors.push(duplicate(game.actors.get(id)));
    }
    return subActors;
  }
  /* -------------------------------------------- */
  async addSubActor( subActorId) {
    let subActors = duplicate( this.data.data.subactors);
    subActors.push( subActorId);
    await this.update( { 'data.subactors': subActors } );
  }
  /* -------------------------------------------- */
  async delSubActor( subActorId) {
    let newArray = [];
    for (let id of this.data.data.subactors) {
      if ( id != subActorId) {
        newArray.push( id);
      }
    }
    await this.update( { 'data.subactors': newArray } );
  }

  /* -------------------------------------------- */
  setDefenseMode( rollData ) {
    console.log("DEFENSE MODE IS SET FOR", this.name);
    this.data.defenseRollData = rollData;
    this.data.defenseDefenderId = rollData.defenderId;
    this.data.defenseAttackerId = rollData.attackerId;
  }
  /* -------------------------------------------- */
  clearDefenseMode( ) {
    this.data.defenseDefenderId = undefined;
    this.data.defenseAttackerId = undefined;
    this.data.defenseRollData = undefined;
  }

  /* -------------------------------------------- */
  syncRoll( rollData ) {
    let linkedRollId = PegasusUtility.getDefenseState(this.id);
    if ( linkedRollId) {
      rollData.linkedRollId = linkedRollId;
    }
    this.lastRollId = rollData.rollId;
    PegasusUtility.saveRollData( rollData );
  }

  /* -------------------------------------------- */
  getStat( statKey) {
    let stat
    if (statKey == 'mr') {
      stat = duplicate(this.data.data.mr);
    } else {
      stat = duplicate(this.data.data.statistics[statKey]);
    }
    stat.dice = PegasusUtility.getDiceFromLevel(stat.value);
    return stat;
  }

  /* -------------------------------------------- */
  getOneSpec( specId) {
    let spec = this.data.items.find( item => item.type == 'specialisation' && item.id == specId);
    if (spec) {
      spec = duplicate(spec);
      spec.data.dice = PegasusUtility.getDiceFromLevel(spec.data.level);
    }
    return spec;
  }

  /* -------------------------------------------- */
  updatePerkRounds( itemId, roundValue) {
    let item = this.items.get( itemId) 
    if (item) {
      this.updateEmbeddedDocuments( 'Item', [ { _id: item.id, 'data.roundcount': roundValue }] );
    }
  }

  /* -------------------------------------------- */
  async rollMR() {
    let mr = duplicate( this.data.data.mr) ;
    if (mr) {
      mr.dice = PegasusUtility.getDiceFromLevel(mr.value);
      let rollData = {
        rollId:randomID(16),
        mode: "MR",
        alias: this.name, 
        actorImg: this.img,
        actorId: this.id,
        img: this.img,
        rollMode: game.settings.get("core", "rollMode"),
        title: `${mr.label} `,
        stat: mr,
        activePerks: duplicate(this.getActivePerks()),
        optionsDiceList: PegasusUtility.getOptionsDiceList(),
        bonusDicesLevel: 0, 
        hindranceDicesLevel: 0,
        otherDicesLevel: 0,
      }

      this.syncRoll( rollData);
      let rollDialog = await PegasusRollDialog.create( this, rollData);
      console.log(rollDialog);
      rollDialog.render( true );
    } else {
      ui.notifications.warn("MR not found !");
    }
  }

    /* -------------------------------------------- */
    getCommonRollData( ) {
    let rollData = {
      rollId:randomID(16),
      alias: this.name, 
      actorImg: this.img,
      actorId: this.id,
      img: this.img,
      rollMode: game.settings.get("core", "rollMode"),
      activePerks: duplicate(this.getActivePerks()),
      optionsDiceList: PegasusUtility.getOptionsDiceList(),
      bonusDicesLevel: 0, 
      hindranceDicesLevel: 0,
      otherDicesLevel: 0,
    }
    return rollData
  }

  /* -------------------------------------------- */
  async startRoll( rollData) {
    this.syncRoll( rollData);
    let rollDialog = await PegasusRollDialog.create( this, rollData);
    console.log(rollDialog);
    rollDialog.render( true );

  }

  /* -------------------------------------------- */
  rollPool( statKey, useSPec) { 
    let stat = this.getStat(statKey);
    if (stat) {
      let rollData = this.getCommonRollData()
      rollData.mode  = "stat"
      rollData.specList = this.getRelevantSpec( statKey)
      rollData.selectedSpec = "0"
      rollData.stat  = stat;

      this.startRoll(rollData);
    } else {
      ui.notifications.warn("Statistic not found !");
    }
  }
  /* -------------------------------------------- */
  rollUnarmedAttack() { 
    let stat = this.getStat('com');
    if (stat) {
      let rollData = this.getCommonRollData()
      rollData.mode  = "stat"
      rollData.title = `Unarmed Attack`;
      rollData.stat  = stat;
      rollData.damages = this.getStat('str');

      this.startRoll(rollData);
    } else {
      ui.notifications.warn("Statistic not found !");
    }
  }

  /* -------------------------------------------- */
  rollStat(statKey) {    
    let stat = this.getStat(statKey) ;
    if (stat) {
      let rollData = this.getCommonRollData()
      rollData.mode  = "stat"
      rollData.title = `Stat ${stat.label}`;
      rollData.stat  = stat;

      this.startRoll(rollData);
    } else {
      ui.notifications.warn("Statistic not found !");
    }
  }
  
  /* -------------------------------------------- */
  async rollSpec( specId ) {
    let spec = this.getOneSpec( specId) 
    if (spec) {
      let rollData  = this.getCommonRollData()
      rollData.mode =  "spec"
      rollData.title = `Spec. : ${spec.name} `,
      rollData.stat = this.getStat( spec.data.statistic )
      rollData.spec = spec

      this.startRoll(rollData);
    } else {
      ui.notifications.warn("Specialisation not found !");
    }
  }

  /* -------------------------------------------- */
  updateWithTarget( rollData) {
    let objectDefender
    let target = WotGUtility.getTarget();
    if ( !target) {
      ui.notifications.warn("You are using a Weapon without a Target.");
    } else  {
      let defenderActor = game.actors.get(target.data.actorId);
      objectDefender = WotGUtility.data(defenderActor);
      objectDefender = mergeObject(objectDefender, target.data.actorData);
      rollData.defender = objectDefender;
      rollData.attackerId    = this.id;
      rollData.defenderId    = objectDefender._id;

      console.log("ROLLDATA DEFENDER !!!", rollData);
    }    
  }

  /* -------------------------------------------- */
  async deleteAllItemsByType( itemType) {
    let items = this.data.items.filter( item => item.type == itemType);
    await this.deleteEmbeddedDocuments( 'Item', items);
  }

  /* -------------------------------------------- */
  async addItemWithoutDuplicate( newItem ) {
    let item = this.data.items.find( item => item.type == newItem.type && item.name.toLowerCase() == newItem.name.toLowerCase() )
    if ( !item ) {
      await this.createEmbeddedDocuments( 'Item', [newItem]);
    }
  }

  /* -------------------------------------------- */
  computeNRGHealth( ) {
    let phyDiceValue = PegasusUtility.getDiceValue(this.data.data.statistics.phy.value);
    if ( phyDiceValue!=this.data.data.secondary.health.max) {
      this.update( {'data.secondary.health.max': phyDiceValue, 'data.secondary.health.value': phyDiceValue} )
    }
    let mndDiceValue = PegasusUtility.getDiceValue(this.data.data.statistics.mnd.value);
    if ( mndDiceValue!=this.data.data.secondary.delirium.max) {
      this.update( {'data.secondary.delirium.max': mndDiceValue, 'data.secondary.delirium.value': mndDiceValue} )
    }
    let stlDiceValue = PegasusUtility.getDiceValue(this.data.data.statistics.stl.value);
    if ( stlDiceValue != this.data.data.secondary.stealthhealth.max) {
      this.update( {'data.secondary.stealthhealth.max': stlDiceValue, 'data.secondary.stealthhealth.value': stlDiceValue} )
    }
    let socDiceValue = PegasusUtility.getDiceValue(this.data.data.statistics.soc.value);
    if ( socDiceValue!=this.data.data.secondary.socialhealth.max) { 
      this.update( {'data.secondary.socialhealth.max': socDiceValue, 'data.secondary.socialhealth.value': socDiceValue} )
    }

    let nrgValue = PegasusUtility.getDiceValue(this.data.data.statistics.foc.value);
    if ( nrgValue!= this.data.data.nrg.max) {
      this.update( {'data.nrg.max': nrgValue, 'data.nrg.value': nrgValue} )
    }

    let mrLevel = (this.data.data.statistics.agi.value + this.data.data.statistics.str.value) - this.data.data.statistics.phy.value
    mrLevel = (mrLevel < 1) ? 1 : mrLevel;
    if ( mrLevel!= this.data.data.mr.value) {
      this.update( {'data.mr.value': mrLevel } );  
    }
  }

  /* -------------------------------------------- */
  async modStat( key, inc=1) {
    let stat = duplicate(this.data.data.statistics[key])        
    stat.mod += parseInt(inc)
    await this.update( { [`data.statistics.${key}`] : stat } )
  }
  
  /* -------------------------------------------- */
  async valueStat( key, inc=1) {
    key = key.toLowerCase()
    let stat = duplicate( this.data.data.statistics[key] )        
    stat.value += parseInt(inc)
    await this.update( { [`data.statistics.${key}`] : stat } )
  }

  /* -------------------------------------------- */
  async addIncSpec( spec, inc=1) {
    console.log("Using spec : ", spec, inc)
    let specExist = this.data.items.find( item => item.type == 'specialisation' && item.name.toLowerCase() == spec.name.toLowerCase())
    if (specExist) {
      specExist = duplicate(specExist)
      specExist.data.level += inc;
      let update = { _id: specExist._id, "data.level": specExist.data.level };
      await this.updateEmbeddedDocuments('Item', [ update ]);
    } else {
      spec.data.level += inc;
      await this.createEmbeddedDocuments( 'Item', [ spec ]);
    }
  }

  /* -------------------------------------------- */
  applyAbility( ability, updates = []) {
    if ( ability.data.affectedstat != "notapplicable") {
      let stat = duplicate(this.data.data.statistics[ability.data.affectedstat])        
      stat.value += parseInt(ability.data.statlevelincrease)
      stat.mod += parseInt(ability.data.statmodifier)
      updates[`data.statistics.${ability.data.affectedstat}`] = stat
    } 
  }
  /* -------------------------------------------- */
  async applyRace( race ) {
    let updates = { 'data.racename':race.name }
    let newItems = []
    await this.deleteAllItemsByType( 'race')    
    newItems.push(race);

    for (let ability of race.data.abilities) {
      newItems.push(ability);
      this.applyAbility( ability, updates)
    }
    if ( race.data.powersgained) {
      for (let power of race.data.powersgained) {
        newItems.push(power);
      }
    }
    if ( race.data.specialisations) {
      for (let spec of race.data.specialisations) {
        newItems.push(spec);
      }
    }
    if ( race.data.attackgained) {
        for (let weapon of race.data.attackgained) {
        newItems.push(weapon);
      }
    }
    if ( race.data.armorgained) {
      for (let armor of race.data.armorgained) {
        newItems.push(armor);
      }
    }

    await this.update( updates )
    await this.createEmbeddedDocuments('Item', newItems)
    console.log("Updates", updates, newItems)
    console.log("Updated actor", this)
  }

  /* -------------------------------------------- */
  getIncreaseStatValue( updates, statKey) {
    let stat = duplicate(this.data.data.statistics[statKey])
    stat.value += 1;
    updates[`data.statistics.${statKey}`] = stat
  }

  /* -------------------------------------------- */
  async applyRole( role ) {
    console.log("ROLE", role)

    let updates = { 'data.rolename': role.name }
    let newItems = []
    await this.deleteAllItemsByType( 'role')    
    newItems.push(role);

    this.getIncreaseStatValue( updates, role.data.statincrease1)
    this.getIncreaseStatValue( updates, role.data.statincrease2)

    //newItems = newItems.concat(duplicate(role.data.specialisationsplus1))
    newItems = newItems.concat(duplicate(role.data.specialperk))

    await this.update( updates )
    await this.createEmbeddedDocuments('Item', newItems)
  }
  
  /* -------------------------------------------- */
  async rollPower( powId ) {
      let power = this.data.items.find( item => item.type == 'power' && item.id == powId);
      if (power) {        
        let rollData = {
          mode: "power",
          alias: this.name, 
          actorImg: this.img,
          actorId: this.id,
          img: power.img,
          rollMode: game.settings.get("core", "rollMode"),
          title: `Power ${power.name} `,
          power: duplicate(power),
          activePerks: duplicate(this.getActivePerks()),
          optionsDiceList: PegasusUtility.getOptionsDiceList(),
          bonusDicesLevel: 0, 
          hindranceDicesLevel: 0,
          otherDicesLevel: 0,
        }

        this.updateWithTarget(rollData);

        this.syncRoll( rollData);
  
        let rollDialog = await PegasusRollDialog.create( this, rollData);
        console.log(rollDialog);
        rollDialog.render( true );
      } else {
        ui.notifications.warn("Technique not found !");
      }
    }
  
  /* -------------------------------------------- */
  async rollWeapon( weaponId  ) {
    let weapon = this.data.items.find( item => item.id == weaponId);
    console.log("WEAPON :", weaponId, weapon );
        
    if ( weapon ) {
      
      weapon = duplicate(weapon);
      this.checkAndPrepareWeapon( weapon );
      let rollData = {
        mode: 'weapon',
        actorType: this.type,
        alias: this.name, 
        actorId: this.id,
        img: weapon.img,
        rollMode: game.settings.get("core", "rollMode"),
        title: "Attack : " + weapon.name,
        weapon: weapon,
        activePerks: duplicate(this.getActivePerks()),
        optionsDiceList: PegasusUtility.getOptionsDiceList(),
        bonusDicesLevel: 0, 
        hindranceDicesLevel: 0,
        otherDicesLevel: 0,
    }

      this.updateWithTarget(rollData);

      this.syncRoll( rollData);

      let rollDialog = await PegasusRollDialog.create( this, rollData);
      console.log("WEAPON ROLL", rollData);
      rollDialog.render( true );
    } else {
      ui.notifications.warn("Weapon not found !", weaponId);
    }
  }

}
