import { SoSCardDeck } from "./sos-card-deck.js";
import { SoSUtility } from "./sos-utility.js";
import { SoSFlipDialog } from "./sos-flip-dialog.js";


/* -------------------------------------------- */
/**
 * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
 * @extends {Actor}
 */
export class SoSActor 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;
    }

    data.items = [];
    let compendiumName = "foundryvtt-shadows-over-sol.skills";
    if ( compendiumName ) {
      let skills = await SoSUtility.loadCompendium(compendiumName);
      data.items = data.items.concat( skills );
    }
    compendiumName = "foundryvtt-shadows-over-sol.consequences";
    if ( compendiumName ) {
      let consequences = await SoSUtility.loadCompendium(compendiumName)
      data.items = data.items.concat(consequences);
    }

    return super.create(data, options);
  }

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

    if ( !this.cardDeck ) {
      this.cardDeck = new SoSCardDeck();
      this.cardDeck.initCardDeck( this, this.data.data.internals.deck );
    }
    this.controlScores();
  }
  /* -------------------------------------------- */
  getEdgesCard( ) {
    let edgesCard = duplicate(this.cardDeck.data.cardEdge);
    for (let edge of edgesCard) {
      edge.path = `systems/foundryvtt-shadows-over-sol/img/cards/${edge.cardName}.webp`
    }
    return edgesCard;
  }
  /* -------------------------------------------- */
  resetDeckFull( ) {
    this.cardDeck.shuffleDeck();
    this.cardDeck.drawEdge( this.data.data.scores.edge.value );
    this.saveDeck();
  }
  /* -------------------------------------------- */
  drawNewEdge( ) {  
    this.cardDeck.drawEdge( 1 );
    this.saveDeck();
  }
  /* -------------------------------------------- */
  resetDeck() {
    
  }

  /* -------------------------------------------- */
  saveDeck( ) {
    let deck = { deck: duplicate(this.cardDeck.data.deck), 
                 discard: duplicate(this.cardDeck.data.discard),
                 cardEdge: duplicate(this.cardDeck.data.cardEdge) 
                }
    this.update( { 'data.internals.deck': deck });
  }

  /* -------------------------------------------- */
  getDefense( ) {
    return this.data.data.scores.defense;    
  }  
  /* -------------------------------------------- */
  computeDefense() {
    return { value: Math.ceil((this.data.data.stats.speed.value + this.data.data.stats.perception.value + this.data.data.stats.dexterity.value) / 2),
             critical: this.data.data.stats.speed.value + this.data.data.stats.perception.value + this.data.data.stats.dexterity.value
            }
  }  
  /* -------------------------------------------- */
  getEdge( ) {
    return this.data.data.scores.edge.value;
  }  
  /* -------------------------------------------- */
  getEncumbrance( ) {
    return this.data.data.scores.encumbrance.value;
  }  
  /* -------------------------------------------- */
  computeEdge( ) {
    return Math.ceil( (this.data.data.stats.intelligence.value + this.data.data.stats.charisma.value) / 2) + this.data.data.scores.edge.bonus;
  }
  /* -------------------------------------------- */
  getShock( ) {
    return this.data.data.scores.shock.value;
  }
  computeShock() {
    return Math.ceil( this.data.data.stats.endurance.value + this.data.data.stats.determination.value + this.data.data.scores.dr.value);
  }
  /* -------------------------------------------- */
  getWound( ) {
    return this.data.data.scores.wound.value;
  }
  computeWound() {
    return Math.ceil( (this.data.data.stats.strength.value + this.data.data.stats.endurance.value) / 2);
  }

  /* -------------------------------------------- */
  async controlScores() {
    // Defense check
    let defenseData = this.getDefense();
    let newDefenseData = this.computeDefense();
    if ( defenseData.value != newDefenseData.value || defenseData.critical != newDefenseData.critical) {
      await this.update( {'data.scores.defense': newDefenseData});
    }
    // Edge check
    if ( this.getEdge() != this.computeEdge() ) {
      await this.update( {'data.scores.edge.value': this.computeEdge()});
    }
    // Encumbrance
    if ( this.getEncumbrance() != this.data.data.stats.strength.value ) {
      await this.update( {'data.scores.encumbrance.value': this.data.data.stats.strength.value });
    }
    // Shock
    if ( this.getShock() != this.computeShock() ) {
      await this.update( {'data.scores.shock.value': this.computeShock() });
    }
    // Wounds
    if ( this.getWound() != this.computeWound() ) {
      await this.update( {'data.scores.wound.value': this.computeWound() });
    }
  }

  /* -------------------------------------------- */
  async rollStat( statKey ) {

    let flipData = {
      mode: 'stat',
      stat: duplicate(this.data.data.stats[statKey]),
      actor: this,
      modifierList: SoSUtility.fillRange(-10, +10),
      tnList: SoSUtility.fillRange(6, 20)
    }
    let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData);
    new SoSFlipDialog(flipData, html).render(true);

  }
  
  /* -------------------------------------------- */
  async rollSkill( skill ) {
    let flipData = {
      mode: 'skill',
      statList: duplicate(this.data.data.stats),
      skill: duplicate(skill),
      actor: this,
      modifierList: SoSUtility.fillRange(-10, +10),
      tnList: SoSUtility.fillRange(6, 20)
    }
    flipData.statList['nostat'] = { label: "No stat (ie defaulting skills)", value: 0, cardsuit: "none" }
    let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData);
    new SoSFlipDialog(flipData, html).render(true);
  }
}
