
export default class PrismRPGUtils {

  /* -------------------------------------------- */
  static async loadCompendiumData(compendium) {
    const pack = game.packs.get(compendium)
    return await pack?.getDocuments() ?? []
  }

  /* -------------------------------------------- */
  static async loadCompendium(compendium, filter = item => true) {
    let compendiumData = await PrismRPGUtils.loadCompendiumData(compendium)
    return compendiumData.filter(filter)
  }

  /* -------------------------------------------- */
  static setHookListeners() {

    Hooks.on('renderTokenHUD', async (hud, html, token) => {
      const lossHPButton = await foundry.applications.handlebars.renderTemplate('systems/fvtt-prism-rpg/templates/loss-hp-hud.hbs', {})
      $(html).find('div.left').append(lossHPButton);
      $(html).find('img.prism-hp-loss-hud').click((event) => {
        event.preventDefault();
        let hpMenu = $(html).find('.hp-loss-wrap')[0]
        if (hpMenu.classList.contains("hp-loss-hud-disabled")) {
          $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-active');
          $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-disabled');
          $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-active');
          $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-disabled');
          $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-active');
          $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-disabled');
        } else {
          $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active');
          $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled');
          $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active');
          $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled');
          $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active');
          $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled');
        }
      })
      $(html).find('.loss-hp-hud-click').click((event) => {
        event.preventDefault();
        let hpLoss = event.currentTarget.dataset.hpValue;
        if (token) {
          let tokenFull = canvas.tokens.placeables.find(t => t.id === token._id);
          console.log(tokenFull, token)
          let actor = tokenFull.actor;
          actor.applyDamage(Number(hpLoss));
          $(html).find('.hp-loss-wrap')[0].classList.remove('hp-loss-hud-active');
          $(html).find('.hp-loss-wrap')[0].classList.add('hp-loss-hud-disabled');
          $(html).find('.hp-loss-wrap')[1].classList.remove('hp-loss-hud-active');
          $(html).find('.hp-loss-wrap')[1].classList.add('hp-loss-hud-disabled');
          $(html).find('.hp-loss-wrap')[2].classList.remove('hp-loss-hud-active');
          $(html).find('.hp-loss-wrap')[2].classList.add('hp-loss-hud-disabled');
        }
      })
    })
  }

  /* -------------------------------------------- */
  static handleSocketEvent(msg = {}) {
    console.log(`handleSocketEvent !`, msg)
    let actor
    switch (msg.type) {
      case "rollInitiative":
        actor = game.actors.get(msg.actorId)
        actor.system.rollInitiative(msg.combatId, msg.combatantId)
        break
      case "rollProgressionDice":
        actor = game.actors.get(msg.actorId)
        actor.system.rollProgressionDice(msg.combatId, msg.combatantId, msg.rollProgressionCount)
        break
    }
  }

  static registerHandlebarsHelpers() {

    Handlebars.registerHelper('isNull', function (val) {
      return val == null;
    });
    Handlebars.registerHelper('match', function (val, search) {
      if (val && search) {
        return val?.match(search);
      }
      return false
    });

    Handlebars.registerHelper('exists', function (val) {
      return val != null && val !== undefined;
    });

    Handlebars.registerHelper('isEmpty', function (list) {
      if (list) return list.length === 0;
      else return false;
    });

    Handlebars.registerHelper('notEmpty', function (list) {
      return list.length > 0;
    });

    Handlebars.registerHelper('isNegativeOrNull', function (val) {
      return val <= 0;
    });

    Handlebars.registerHelper('isNegative', function (val) {
      return val < 0;
    });

    Handlebars.registerHelper('isPositive', function (val) {
      return val > 0;
    });

    Handlebars.registerHelper('equals', function (val1, val2) {
      return val1 === val2;
    });

    Handlebars.registerHelper('neq', function (val1, val2) {
      return val1 !== val2;
    });

    Handlebars.registerHelper('gt', function (val1, val2) {
      return val1 > val2;
    })

    Handlebars.registerHelper('lt', function (val1, val2) {
      return val1 < val2;
    })

    Handlebars.registerHelper('gte', function (val1, val2) {
      return val1 >= val2;
    })

    Handlebars.registerHelper('lte', function (val1, val2) {
      return val1 <= val2;
    })
    Handlebars.registerHelper('and', function (val1, val2) {
      return val1 && val2;
    })
    Handlebars.registerHelper('or', function (val1, val2) {
      return val1 || val2;
    })

    Handlebars.registerHelper('or3', function (val1, val2, val3) {
      return val1 || val2 || val3;
    })

    Handlebars.registerHelper('for', function (from, to, incr, block) {
      let accum = '';
      for (let i = from; i < to; i += incr)
        accum += block.fn(i);
      return accum;
    })

    Handlebars.registerHelper('not', function (cond) {
      return !cond;
    })
    Handlebars.registerHelper('inc', function (value) {
      // Extract number from string like "level1" or just parse number
      const num = typeof value === 'string' ? parseInt(value.replace(/\D/g, '')) : parseInt(value);
      return isNaN(num) ? value : num + 1;
    })
    Handlebars.registerHelper('count', function (list) {
      return list.length;
    })
    Handlebars.registerHelper('countKeys', function (obj) {
      return Object.keys(obj).length;
    })
    Handlebars.registerHelper('entries', function (obj) {
      return Object.entries(obj);
    })
    Handlebars.registerHelper('uppercase', function (str) {
      return str ? str.toUpperCase() : '';
    })

    Handlebars.registerHelper('replace', function (str, search, replacement) {
      if (!str) return '';
      return str.replace(search, replacement);
    })

    Handlebars.registerHelper('isEnabled', function (configKey) {
      return game.settings.get("bol", configKey);
    })
    Handlebars.registerHelper('split', function (str, separator, keep) {
      return str.split(separator)[keep];
    })

    // If you need to add Handlebars helpers, here are a few useful examples:
    Handlebars.registerHelper('concat', function () {
      let outStr = '';
      for (let arg in arguments) {
        if (typeof arguments[arg] != 'object') {
          outStr += arguments[arg];
        }
      }
      return outStr;
    })

    Handlebars.registerHelper('add', function (a, b) {
      return parseInt(a) + parseInt(b);
    });
    Handlebars.registerHelper('mul', function (a, b) {
      return parseInt(a) * parseInt(b);
    })
    Handlebars.registerHelper('sub', function (a, b) {
      return parseInt(a) - parseInt(b);
    })
    Handlebars.registerHelper('abbrev2', function (a) {
      return a.substring(0, 2);
    })
    Handlebars.registerHelper('abbrev3', function (a) {
      return a.substring(0, 3);
    })
    Handlebars.registerHelper('valueAtIndex', function (arr, idx) {
      return arr[idx];
    })
    Handlebars.registerHelper('includesKey', function (items, type, key) {
      return items.filter(i => i.type === type).map(i => i.system.key).includes(key);
    })
    Handlebars.registerHelper('includes', function (array, val) {
      return array.includes(val);
    })
    Handlebars.registerHelper('eval', function (expr) {
      return eval(expr);
    })
    Handlebars.registerHelper('isOwnerOrGM', function (actor) {
      console.log("Testing actor", actor.isOwner, game.userId)
      return actor.isOwner || game.isGM;
    })
    Handlebars.registerHelper('upperCase', function (text) {
      if (typeof text !== 'string') return text
      return text.toUpperCase()
    })
    Handlebars.registerHelper('upperFirst', function (text) {
      if (typeof text !== 'string') return text
      return text.charAt(0).toUpperCase() + text.slice(1)
    })
    Handlebars.registerHelper('upperFirstOnly', function (text) {
      if (typeof text !== 'string') return text
      return text.charAt(0).toUpperCase()
    })

    // Handle v12 removal of this helper
    Handlebars.registerHelper('select', function (selected, options) {
      const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected));
      const rgx = new RegExp(' value=[\"\']' + escapedValue + '[\"\']');
      const html = options.fn(this);
      return html.replace(rgx, "$& selected");
    });

  }

  static getLethargyDice(level) {
    for (let s of SYSTEM.SPELL_LETHARGY_DICE) {
      if (Number(level) <= s.maxLevel) {
        return s.dice
      }
    }
  }

  /**
   * Preload Handlebars templates for partials
   * @returns {Promise}
   */
  static async preloadHandlebarsTemplates() {
    const templatePaths = [
      'systems/fvtt-prism-rpg/templates/partial-item-effects.hbs',
      'systems/fvtt-prism-rpg/templates/weapon-types-config.hbs',
      'systems/fvtt-prism-rpg/templates/chat-new-round.hbs',
    ]
    return foundry.applications.handlebars.loadTemplates(templatePaths)
  }

}
