// SPDX-FileCopyrightText: 2022 Johannes Loher
//
// SPDX-License-Identifier: MIT

import { createCheckRoll } from "../../../dice/check-factory";
import { notifications } from "../../../ui/notifications";
import { getGame } from "../../../utils/utils";
import { DS4Item } from "../item";
import { calculateSpellPrice } from "./calculate-spell-price";

export class DS4Spell extends DS4Item {
  /** @override */
  prepareDerivedData() {
    this.system.rollable = this.system.equipped;
    this.system.price = calculateSpellPrice(this.system);
    if (this.system.allowsDefense) {
      this.system.opponentDefense = 0;
    }
  }

  /** @override */
  async roll(options = {}) {
    const game = getGame();

    if (!this.system.equipped) {
      return notifications.warn(
        game.i18n.format("DS4.WarningItemMustBeEquippedToBeRolled", {
          name: this.name,
          id: this.id,
          type: this.type,
        }),
      );
    }

    if (!this.actor) {
      throw new Error(game.i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id }));
    }

    const ownerSystemData = this.actor.system;
    const hasComplexModifier = this.system.spellModifier.complex !== "";
    if (hasComplexModifier === undefined) {
      notifications.info(
        game.i18n.format("DS4.InfoManuallyEnterSpellModifier", {
          name: this.name,
          spellModifier: this.system.spellModifier.complex,
        }),
      );
    }
    const spellType = this.system.spellType;
    const opponentDefense = this.system.opponentDefense;
    const checkTargetNumber =
      ownerSystemData.combatValues[spellType].total + (hasComplexModifier ? 0 : this.system.spellModifier.numerical);
    const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker });
    const flavor =
      opponentDefense !== undefined && opponentDefense !== 0
        ? "DS4.ItemSpellCheckFlavorWithOpponentDefense"
        : "DS4.ItemSpellCheckFlavor";
    /** @type {import("../../../dice/check-factory").DS4CheckFactoryOptions["flavorData"]} */
    const flavorData = {
      actor: speaker.alias ?? this.actor.name,
      spell: this.name,
    };
    if (opponentDefense !== undefined && opponentDefense !== 0) {
      flavorData.opponentDefense = (opponentDefense < 0 ? "" : "+") + opponentDefense;
    }

    await createCheckRoll(checkTargetNumber, {
      rollMode: game.settings.get("core", "rollMode"),
      maximumCoupResult: ownerSystemData.rolling.maximumCoupResult,
      minimumFumbleResult: ownerSystemData.rolling.minimumFumbleResult,
      flavor: flavor,
      flavorData: flavorData,
      speaker,
    });

    /**
     * A hook event that fires after an item is rolled.
     * @function ds4.rollItem
     * @memberof hookEvents
     * @param {DS4Item} item    Item being rolled.
     */
    Hooks.callAll("ds4.rollItem", this);
  }
}
