import BaseItem from "./base-item.mjs";

const {
    BooleanField,
    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 NumberField({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() {
    }

    /**
     * Handle clickable rolls.
     * @param {Event} event   The originating click event
     * @private
     */
    async roll() {
        const owner = this.parent.parent
        let roll1 = new Roll("3d20", owner.getRollData());

        let evaluated1 = (await roll1.evaluate())

        const dsaDieRollEvaluated = this._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: game.settings.get('core', 'rollMode'),
            })
        } else { // misserfolg
            evaluated1.toMessage({
                speaker: ChatMessage.getSpeaker({actor: owner}),
                flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Gepatzt' : ''} mit ${Math.abs(dsaDieRollEvaluated.tap)} Punkten daneben`,
                rollMode: game.settings.get('core', 'rollMode'),
            })
        }
    }

    _evaluateRoll(rolledDice, {
        taw,
        lowerThreshold = 1,
        upperThreshold = 20,
        countToMeisterlich = 3,
        countToPatzer = 3,
        werte = []
    }) {
        let tap = taw;
        let meisterlichCounter = 0;
        let patzerCounter = 0;
        let failCounter = 0;

        rolledDice.forEach((rolledDie, index) => {
            if (tap < 0 && rolledDie.result > werte[index]) {
                tap -= rolledDie.result - werte[index];
                if (tap < 0) { // konnte nicht vollständig ausgeglichen werden
                    failCounter++;
                }
            } else if (rolledDie.result > werte[index]) { // taw ist bereits aufgebraucht und wert kann nicht ausgeglichen werden
                tap -= rolledDie.result - werte[index];
                failCounter++;
            }
            if (rolledDie.result <= lowerThreshold) meisterlichCounter++;
            if (rolledDie.result > upperThreshold) patzerCounter++;
        })

        return {
            tap,
            meisterlich: meisterlichCounter === countToMeisterlich,
            patzer: patzerCounter === countToPatzer,
        }
    }
}
