text: import { MODULE } from '../module.js';
  import { logger } from '../logger.js';
  import { ActionDialog } from '../apps/action-dialog.js'
  import { queueUpdate } from './update-queue.js'
  
  const NAME = "LegendaryActionManagement";
  
  /** @todo need to support an array of actors, not just a single one */
  class LegendaryActionDialog extends ActionDialog {
  
    /** @override */
    constructor(combatants) {
      
      /* Localize title */
      const title = MODULE.format("DND5E.LegAct");
  
      /* construct an action dialog using only legendary actions */
      super(combatants, {legendary: true, title, id:'legact-action-dialog'});
    }
  
  }
  
  
  /**
   * LegendaryActionManagement
   *  This Module strictly manages Legendary action economy per the dnd5e rules.
   */
  export class LegendaryActionManagement{
  
    /** @public */
    static register(){
      this.settings();
      this.hooks();
    }
  
    /** @public */
    static settings(){
      const config = false;
      const settingsData = {
        legendaryActionRecharge : {
          scope : "world", config, group: "npc-features", default: false, type: Boolean,
        },
        legendaryActionHelper : {
          scope : "world", config, group: "npc-features", default: false, type: Boolean,
        }
      };
  
      MODULE.applySettings(settingsData);
    }
  
    /** @public */
    static hooks() {
      Hooks.on('createCombatant', LegendaryActionManagement._createCombatant);
      Hooks.on('updateCombat', LegendaryActionManagement._updateCombat);
    }
  
    /**
     * Check Combatant for Legendary Actions, store information on the combat.
     *  actorid, [itemid], 
     * 
     * @param {Combatant} combatant 
     */
    static _createCombatant(combatant) {
  
      /* do not run if not the first GM, but always flag regardless of enable state */
      if (!MODULE.isFirstGM()) return;
  
      const hasLegendary = !!combatant.actor?.items.find((i) => i.data?.data?.activation?.type === "legendary")
  
      /* flag this combatant as a legendary actor for quick filtering */
      if (hasLegendary){
        logger.debug(`${NAME} | flagging as legendary combatant: ${combatant.name}`, combatant);
        queueUpdate( async () => await combatant.setFlag(MODULE.data.name, 'hasLegendary', true) )
      }
  
    }
  
    /** @private */
    /* 
     * @param {*} combat 
     * @param {*} changed 
     * @returns 
     */
    static _updateCombat(combat, changed) {
  
      /* do not run if not the first GM or the feature is not enabled */
      if (!MODULE.isFirstGM()) return;
  
      /* only trigger legendary actions on a legit turn change */
      if (!MODULE.isTurnChange(combat, changed)) return;
  
      const previousId = combat.previous?.combatantId;
  
      /* run the leg action helper dialog if enabled */
      if (MODULE.setting('legendaryActionHelper')) {
  
        /* Collect legendary combatants (but not the combatant whose turn just ended) */
        let legendaryCombatants = combat.combatants.filter( combatant => combatant.getFlag(MODULE.data.name, 'hasLegendary') && combatant.id != previousId );
  
        /* only prompt for actions from alive creatures with leg acts remaining */
        legendaryCombatants = legendaryCombatants.filter( combatant => getProperty(combatant.actor, 'data.data.resources.legact.value') ?? 0 > 0 );
        legendaryCombatants = legendaryCombatants.filter( combatant => getProperty(combatant.actor, 'data.data.attributes.hp.value') ?? 0 > 0 );
  
        /* send list of combantants to the action dialog subclass */
        if (legendaryCombatants.length > 0) {
          LegendaryActionManagement.showLegendaryActions(legendaryCombatants);
        }
  
      }
  
      /* recharge the legendary actions, if enabled */
      if (MODULE.setting('legendaryActionRecharge')) {
  
        /* once the dialog for the "in-between" turn has been rendered, recharge legendary actions
         * for the creature whose turn just ended. This is not entirely RAW, but due to order
         * of operations it must be done 'late'. Since a creature cannot use a legendary
         * action at the end of its own turn, nor on its own turn, recharging at end of turn
         * rather than beginning of turn is functionally equivalent. */
        if (previousId) {
  
          /* does the previous combatant have legendary actions? */
          const previousCombatant = combat.combatants.get(previousId);
          if(!!previousCombatant?.getFlag(MODULE.data.name, 'hasLegendary')) {
            LegendaryActionManagement.rechargeLegendaryActions(previousCombatant);
          }
        }
  
      }
    }
  
    /** @private */
    /*
     * Generates the action dialog for legendary actions 
     * @param {Array of Object} combatants
     */
    static showLegendaryActions(combatants) {
      new LegendaryActionDialog(combatants).render(true);
    }
  
    /** @private */
    /*
     * @param {Combatant} combatant
     *
     * @return {Actor5e} modified actor document
     */
    static rechargeLegendaryActions(combatant) {
  
      if (!combatant.actor || !combatant.token) {
        return;
      }
  
      let legact = getProperty(combatant.actor, 'data.data.resources.legact');
  
      /* does this creature have the legendary action counter? */
      if (!!legact && legact.value !== null) {
  
        /* only reset if needed */
        if (legact.value < legact.max) {
          ui.notifications.info(game.i18n.format("DND5EH.CombatLegendary_notification", {max: legact.max, tokenName: combatant.token.name}))
  
          /* send the reset update and sheet refresh */
          queueUpdate( async () => {
            const newActor = await combatant.actor.update({'data.resources.legact.value': legact.max});
            newActor.sheet.render(false);
          });
  
        }
      }
  
      return;
    }
  
  }
  