"use strict";

const Spell  = require('@app/content/spells').Spell;
const Random = require('@util/random');

const SPELL_SCHOOLS = require('@constants').SPELL_SCHOOLS;
const FLAGS         = require('@constants').FLAGS;

const WINDWALL_TURNS            = require('@constants').WINDWALL_TURNS;
const WINDWALL_KNOCKBACK_CHANCE = require('@constants').WINDWALL_KNOCKBACK_CHANCE;

const CHILLED_TURNS = 10;

const MIN_DAMAGE = 20;
const MAX_DAMAGE = 40;
const MP_COST = 10;

class WindwallSpell extends Spell {
  constructor() {
    super({
      type: 'windwall',
      displayName: "Windwall",
      description: `Creates a wall of brutal wind for ${WINDWALL_TURNS} turns.  Any enemies attempting to close from ranged to melee will take damage and have a ${WINDWALL_KNOCKBACK_CHANCE}% chance of being knocked back to ranged and chilled.`,
      school: SPELL_SCHOOLS.CONJURATION,
      mpCost: MP_COST,
      minDamage: MIN_DAMAGE,
      maxDamage: MAX_DAMAGE,
      gold: 2500,
      canCastFighting: true,
      doesDamage: true,
    });
  }

  /**
   * Set up that windwall.
   *
   * @param {Character} character - The character casting the spell.
   *
   * @return {array}
   */
  castFighting(character) {
    character.mp -= this.getMpCost(character);
    character.enemy.setFlag(FLAGS.WINDWALL_TURNS, WINDWALL_TURNS + 1);
    character.enemy.setFlag(FLAGS.WINDWALL_DAMAGE, this.getSpellDamage(character));

    return [`:wind_blowing_face: Starting with a small breeze and culminating with a massive gust, you set up a wall of wind between you and ${character.enemy.getDisplayName(character)}.`];
  }

  /**
   * Enemy has tried to enter the windwall.  Blow them around a bit!
   *
   * @param {Enemy} enemy - The enemy to blow around.
   * @param {Character} character - The character who cast the windwall spell.
   *
   * @return {array} The text generated by this action.
   */
  static blow(enemy, character) {
    let messages = [];

    const damage = enemy.getFlag(FLAGS.WINDWALL_DAMAGE);
    enemy.decreaseHp(damage);

    if (WindwallSpell.isKnockedBack()) {
      messages.push(`${enemy.getDisplayName(character)} ${enemy.isAre} blown about by the wind, takes *${damage}* damage, is chilled, and is knocked back to range!`);
    }
    else {
      character.clearFlag(FLAGS.IS_RANGED);
      enemy.clearFlag(FLAGS.IS_RANGED);

      messages.push(`${enemy.getDisplayName(character)} ${enemy.isAre} blown about by the wind and takes *${damage}* damage and is chilled, but manages to bully through and close the distance!`);
    }

    messages = messages.concat(enemy.addStatusChilled(CHILLED_TURNS));

    return messages;
  }

  /**
   * If enemy is knocked back when being blown about in a Windwall.
   *
   * @return {boolean}
   */
  static isKnockedBack() {
    return Random.between(1, 100) <= WINDWALL_KNOCKBACK_CHANCE;
  }
}

module.exports = WindwallSpell;