import BaseItem from "./baseItem.mjs";
import {evaluateRoll} from "../globals/DSARoll.mjs";

const {
    DocumentIdField,
    ArrayField,
    NumberField,
    SchemaField,
    StringField,
    HTMLField
} = foundry.data.fields;

export class SkillDataModel extends BaseItem {

    static defineSchema() {
        return {
            name: new StringField({required: true}),
            gruppe: new StringField({required: true}),
            taw: new NumberField({integer: true, initial: 0}),
            at: new NumberField({required: false, integer: true, initial: 0}),
            pa: new NumberField({required: false, integer: true, nullable: true, initial: 0}),
            probe: new ArrayField(new StringField(), {exact: 3}), // References one of the eight attributes by name
            voraussetzung: new SchemaField({
                talent: new DocumentIdField(),
                wert: new NumberField(),
            }, {required: false}), // Required skills at a given level
            talent: new HTMLField({required: true}),
            behinderung: new StringField({required: false}), // BE-X
            komplexität: new NumberField({required: false}), // In case of languages
        }
    }

    /**
     * Augment the basic Item data model with additional dynamic data.
     */
    prepareData() {
    }

    /**
     * Prepare a data object which is passed to any Roll formulas which are created related to this Item
     * @private
     */
    getRollData() {
    }

    /**
     * Determines the values to consult for the given type of roll (normal: talent roll, attack: AT, parry: PA
     * @returns {{NORMAL: string, ATTACK: string, PARRY: string}}
     * @constructor
     */
    get SKILL_MODE() {
        return {
            NORMAL: "NORMAL",
            ATTACK: "ATTACK",
            PARRY: "PARRY",
        }
    }


    /**
     *
     * @param rollMode {["publicroll","gmroll"] }
     * @param mode
     * @returns {Promise<void>}
     */
    async roll(rollMode = null, mode = this.SKILL_MODE.NORMAL) {



        rollMode = rollMode ?? game.settings.get('core', 'rollMode');

        switch (mode) {
            case this.SKILL_MODE.NORMAL:
                return this.#talentRoll(rollMode)
            case this.SKILL_MODE.ATTACK:
            case this.SKILL_MODE.PARRY:
                return this.#combatRoll(rollMode, mode)
        }

    }

    async #combatRoll(rollMode, mode) {
        const owner = this.parent.parent

        if (mode === this.SKILL_MODE.ATTACK) {
            owner.rollAttack({
                skill: this.parent._id,
                target: owner._id,
                mod: 0,
                penalty: 0,
                actor: owner,
                circumstance: 0,
                targetNumber: this.at + owner.system.at.basis
            })
        } else {
            owner.rollDefense({
                skill: this.parent._id,
                target: owner._id,
                mod: 0,
                penalty: 0,
                actor: owner,
                circumstance: 0,
                targetNumber: this.pa + owner.system.pa.basis
            })
        }
    }

    async #talentRoll(rollMode) {
        const owner = this.parent.parent

        let roll1 = new Roll("3d20", owner.getRollData());

        let evaluated1 = (await roll1.evaluate())

        const dsaDieRollEvaluated = evaluateRoll(evaluated1.terms[0].results, {
            taw: this.taw,
            werte: [this.probe[0], this.probe[1], this.probe[2]],
        })

        if (dsaDieRollEvaluated.tap >= 0) { // erfolg
            evaluated1.toMessage({
                speaker: ChatMessage.getSpeaker({actor: owner}),
                flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Meisterlich geschafft' : 'Geschafft'} mit ${dsaDieRollEvaluated.tap} Punkten übrig`,
                rollMode,
            })
        } else { // misserfolg
            evaluated1.toMessage({
                speaker: ChatMessage.getSpeaker({actor: owner}),
                flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Gepatzt' : ''} mit ${Math.abs(dsaDieRollEvaluated.tap)} Punkten daneben`,
                rollMode,
            })
        }
    }

}
