import {Talent} from "../data/talent.mjs";
import {ATTRIBUTE} from "../data/attribute.mjs";
import {displayRoll} from "../globals/displayRoll.js";

const {
    ApplicationV2, 
    HandlebarsApplicationMixin
} = foundry.applications.api

export class TalentDialog extends HandlebarsApplicationMixin(ApplicationV2) {

    static DEFAULT_OPTIONS = {
        classes: ['dsa41', 'dialog', 'talent'],
        tag: "form",
        position: {
            width: 480,
            height: 800
        },
        window: {
            resizable: false,
            title: "Talent nutzen"
        },
        form: {
            submitOnChange: true,
            closeOnSubmit: false,
            handler: TalentDialog.#onSubmitForm
        },
        actions: {
            use: TalentDialog.#use,
        }
    }


    static PARTS = {
        form: {
            template: 'systems/DSA_4-1/templates/dialog/talent-dialog.hbs',
        }
    }

    static data = {}

    /**
     *
     * @type {Actor}
     * @private
     */
    _actor = null

    constructor(actor, talentId) {
        super()
        this._actor = actor
        this._talent = this._actor.itemTypes["Skill"].find(p => p._id === talentId)
        this._circumstance = 0
        this._mods = []
    }

    static async #onSubmitForm(event, form, formData) {
        event.preventDefault()

        this._circumstance = formData.object["circumstance"]
        this._mods = []
        Object.entries(formData.object).filter(([key, value]) => key.startsWith("mods.")).forEach(([key, value]) => {
            const [_, suffix] = key.split("mods.")
            if (value != null) {
                this._mods.push({
                    name: suffix,
                    value: value
                })
            }

        })
        this.render({parts: ["form"]})
    }


    static async #use(event, target) {

        const taw = this._talent.system.taw

        let modValue = this._circumstance
        this._mods.forEach(mod => {
            modValue += Number(mod.value)
        })

        const payload = {
            name: this._talent.name,
            taw: taw,
            mod: modValue,
            owner: this._actor,
            eigenschaft1: this._talent.system.probe[0].toLowerCase(),
            eigenschaft2: this._talent.system.probe[1].toLowerCase(),
            eigenschaft3: this._talent.system.probe[2].toLowerCase(),
            eigenschaften: {}
        }

        payload.eigenschaften[this._talent.system.probe[0].toLowerCase()] = this._actor.system.attribute[this._talent.system.probe[0].toLowerCase()].aktuell
        payload.eigenschaften[this._talent.system.probe[1].toLowerCase()] = this._actor.system.attribute[this._talent.system.probe[1].toLowerCase()].aktuell
        payload.eigenschaften[this._talent.system.probe[2].toLowerCase()] = this._actor.system.attribute[this._talent.system.probe[2].toLowerCase()].aktuell

        const result = await new Talent(payload).evaluate("publicroll")

        const context = {
            talent: this._talent.name,
            taw,
            mod: modValue,
            ergebnis: [
                {
                    eigenschaft: this._talent.system.probe[0],
                    eigenschaftWert: taw + modValue < 0 ? this._actor.system.attribute[this._talent.system.probe[0].toLowerCase()].aktuell + (taw + modValue) : this._actor.system.attribute[this._talent.system.probe[0].toLowerCase()].aktuell,
                    wuerfelErgebnis: result.evaluated.terms[0].results[0].result,
                    reduced: taw + modValue < 0
                },
                {
                    eigenschaft: this._talent.system.probe[1],
                    eigenschaftWert: taw + modValue < 0 ? this._actor.system.attribute[this._talent.system.probe[1].toLowerCase()].aktuell + (taw + modValue) : this._actor.system.attribute[this._talent.system.probe[1].toLowerCase()].aktuell,
                    wuerfelErgebnis: result.evaluated.terms[0].results[1].result,
                    reduced: taw + modValue < 0
                },
                {
                    eigenschaft: this._talent.system.probe[2],
                    eigenschaftWert: taw + modValue < 0 ? this._actor.system.attribute[this._talent.system.probe[2].toLowerCase()].aktuell + (taw + modValue) : this._actor.system.attribute[this._talent.system.probe[2].toLowerCase()].aktuell,
                    wuerfelErgebnis: result.evaluated.terms[0].results[2].result,
                    reduced: taw + modValue < 0
                }
            ],
            patzer: result.patzer,
            meisterlich: result.meisterlich,
        }

        if(result.tap>0) {
            context.remaining = Math.abs(result.tap)
        } else if (result.tap===0) {
            context.remaining = 1
        } else {
            context.missing = Math.abs(result.tap)
        }

        await displayRoll(result.evaluated, game.user, this.actor, false, true, 'systems/DSA_4-1/templates/chat/skill-chat-message.hbs', context)

        this.close()
    }

    _configureRenderOptions(options) {
        super._configureRenderOptions(options)

        if (options.window) {
            if (this._talent) {
                options.window.title = this._talent.name
            }

            options.position.height = 640

        }


        return options
    }


    async _prepareContext(options) {
        const context = await super._prepareContext(options)
        context.actor = this._actor
        context.talent = this._talent
        context.colorfulDice = game.settings.get('DSA_4-1', 'optional_colorfuldice')

        context.text = context.talent.system.talent

        context.dice = []
        context.talent.system.probe.forEach(p => {
            context.dice.push({
                wert: this._actor.system.attribute[p.toLowerCase()].aktuell,
                name: p,
                tooltip: ATTRIBUTE[p.toLowerCase()],
            })
        })

        context.mods = [] // ADV, DDV, SF that may influence this talent atleast BE

        const categories = ["Advantage", "SpecialAbility"]
        categories.forEach(category => this._actor.itemTypes[category].forEach(adv => {

            const mods = adv.system.getActiveMod()

            mods?.forEach(mod => {

                if (mod.talent === context.talent.name) {
                    context.mods.push({
                        name: adv.name,
                        value: mod.value,
                        mod: adv.name + "talent",
                        active: this._mods.find(mod => mod.name === adv.name + "talent")
                    })
                }

                if (mod.name) {
                    context.talent.system.probe.forEach(p => {
                        if (mod.name === `attribute.${p.toLowerCase()}.mod`) {
                            context.mods.push({
                                name: adv.name,
                                value: mod.value,
                                mod: adv.name + "eigenschaft",
                                active: this._mods.find(mod => mod.name === adv.name + "eigenschaft")
                            })
                        }
                    })
                }

            })

        }))

        if (context.talent.system.behinderung) { // can be null
            const eBE = context.talent.system.behinderung

            if (eBE === "situationsbedingt") {
                context.mods.push({
                    name: `Behinderung`,
                    value: -this._actor.system.be,
                    mod: "Behinderung",
                    active: this._mods.find(mod => mod.name === "Behinderung")

                })
            } else {
                const be = eval(this._actor.system.be + eBE) // eBE can be *X, +X, -X
                context.mods.push({
                    name: `Behinderung (eBE${eBE})`,
                    value: -be,
                    mod: "Behinderung",
                    active: this._mods.find(mod => mod.name === "Behinderung")
                })
            }

        }


        context.taw = this._talent.system.taw
        context.circumstance = this._circumstance
        context.penalty = 0
        this._mods.forEach(mod => {
            context.penalty += Number(mod.value)
        })

        context.modResult = context.taw + context.circumstance + context.penalty
        context.displayModResult = context.modResult > 0 ? `+${context.modResult}` : context.modResult

        return context
    }
}