export class ActionManager {

    static FREE = "free-action";
    static REGULAR = "regular-action";
    static CONTINUING = "continuing-action";

    static MOVEMENT = "movement-action"
    static DEFENSE = "defense-action"
    static ATTACK = "attack-action"
    static INTERACTION = "interaction";
    static TALENT = "talent-action"
    static SPELL = "spell";
    static DEFAULT = "default"
    static SF = "special-ability"

    constructor(actor) {
        this.actor = actor
    }

    #freeActions = [
        {
            name: "Ausweichen",
            cost: ActionManager.FREE,
            type: ActionManager.DEFENSE,
            source: ActionManager.DEFAULT,
            eval: (options) => {
                if (options?.weapon && options.weapon === "Ausweichen") {
                    return true
                }
                return false
            }
        },
        {
            name: "Rufen",
            cost: ActionManager.FREE,
            type: ActionManager.INTERACTION,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Sich zu Boden fallen lassen",
            cost: ActionManager.FREE,
            type: ActionManager.MOVEMENT,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Waffe oder Gegenstand fallen lassen",
            cost: ActionManager.FREE,
            type: ActionManager.INTERACTION,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "getragenes Artefakt aktivieren",
            cost: ActionManager.FREE,
            type: ActionManager.INTERACTION,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Schnellziehen",
            cost: ActionManager.FREE,
            type: ActionManager.INTERACTION,
            source: ActionManager.SF,
            eval: (options) => {
                const step1 = this.#hatSonderfertigkeit("Schnellziehen", options)
                const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Schnellziehen", options)
                if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) {
                    return step2WithBenefits
                } else
                    return false
            },
        }
    ]

    #regularActions = [
        {
            name: "Nahkampfangriff",
            type: ActionManager.ATTACK,
            cost: ActionManager.REGULAR,
            source: ActionManager.DEFAULT,
            activate: (queue, data) => {
                data.actor.rollAttack(data)
                return true
            },
            eval: (options) => this.#hatWaffeinHand(options),
        },
        {
            name: "Fernkampfangriff",
            type: ActionManager.ATTACK,
            cost: ActionManager.CONTINUING,
            source: ActionManager.DEFAULT,
            cooldown: (options) => 1,
            activate: (queue, data) => {
                data.actor.rollAttack(data)
                return true
            },
            eval: (options) => this.#hatFernkampfWaffeinHand(options),
        },
        {
            name: "Angesagter Fernkampfangriff", // wird durch Scharfer Schuss aus SF ersetzt
            type: ActionManager.ATTACK,
            cost: ActionManager.CONTINUING,
            source: ActionManager.DEFAULT,
            cooldown: (options) => options.mod,
            activate: (queue, data) => {
                data.actor.rollAttack(data)
                return true
            },
            eval: (options) => {
                const step1 = this.#hatFernkampfWaffeinHand(options)
                const step2 = !this.#hatSonderfertigkeit("Scharfschütze", options)
                const step3 = this.#hatSonderfertigkeit("Scharfschütze", options) && !this.#evalSonderfertigkeitRequirements("Scharfschütze", options)
                if (step1 && (step2 || step3)) {
                    return true
                } else
                    return false
            },
            modDescription: "erhöht TP vom Angriff um {}",
            mod: (value) => -value * 2
        },
        {
            name: "Scharfer Schuss",
            type: ActionManager.ATTACK,
            cost: ActionManager.CONTINUING,
            source: ActionManager.SF,
            cooldown: (options) => options.mod - 2,
            activate: (queue, data) => {
                data.actor.rollAttack(data)
                return true
            },
            eval: (options) => {
                const step1 = this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Scharfschütze", options)
                const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Scharfschütze", options)
                if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) {
                    return step2WithBenefits
                } else
                    return false
            },
            modDescription: "erhöht TP vom Angriff um {}",
            mod: (value) => -value
        },
        {
            name: "Schnellschuss",
            type: ActionManager.INTERACTION,
            cost: ActionManager.CONTINUING,
            source: ActionManager.DEFAULT,
            cooldown: (options) => 1,
            activate: (queue) => {
                // get earliest rangedAttack and reduce its cooldown by 1 but also increases its difficulty by 2
                return true
            },
            eval: (options) => this.#hatFernkampfWaffeinHand(options)
        },
        {
            name: "Schnellschuss (Scharfschütze)",
            type: ActionManager.INTERACTION,
            cost: ActionManager.CONTINUING,
            source: ActionManager.SF,
            cooldown: (options) => 1,
            activate: (queue) => {
                // get earliest rangedAttack and reduce its cooldown by 1 but also increases its difficulty by 1
                return true
            },
            eval: (options) => {
                const step1 = this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Scharfschütze", options)
                const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Scharfschütze", options)
                if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) {
                    return step2WithBenefits
                } else
                    return false
            }
        },
        {
            name: "Parade",
            type: ActionManager.DEFENSE,
            cost: ActionManager.REGULAR,
            source: ActionManager.DEFAULT,
            eval: (options) => {
                if (options?.weapon && options.weapon !== "Ausweichen") {
                    return true
                }
                return false
            }
        },
        {
            name: "Meisterparade",
            type: ActionManager.DEFENSE,
            cost: ActionManager.REGULAR,
            source: ActionManager.SF,
            modDescription: "erschwert nächste AT vom Ziel um {}",
            mod: (value) => -value,
            eval: (options) => {
                const step1 = this.#hatWaffeinHand(options) && this.#hatSonderfertigkeit("Meisterparade", options)
                const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Meisterparade", options)
                if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) {
                    return step2WithBenefits
                } else
                    return false
            }
        },
        {
            name: "Bewegen",
            type: ActionManager.MOVEMENT,
            cost: ActionManager.REGULAR,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Position",
            type: ActionManager.MOVEMENT,
            cost: ActionManager.REGULAR,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Finte",
            type: ActionManager.ATTACK,
            cost: ActionManager.REGULAR,
            source: ActionManager.SF,
            modDescription: "verringert PA des Ziels um {}",
            mod: (value) => value,
            activate: (queue, data) => {
                data.actor.rollAttack(data)
                return true
            },
            eval: (options) => {
                const step1 = this.#hatWaffeinHand(options) && this.#hatSonderfertigkeit("Finte", options)
                const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Finte", options)
                if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) {
                    return step2WithBenefits
                } else
                    return false
            }
        },
        {
            name: "Wuchtschlag", // wird durch Wuchtschlag aus SF ersetzt
            type: ActionManager.ATTACK,
            cost: ActionManager.REGULAR,
            source: ActionManager.DEFAULT,
            modDescription: "erhöht TP vom Angriff um {}",
            mod: (value) => -(value * 2),
            activate: (queue, data) => {
                data.actor.rollAttack(data)
                return true
            },
            eval: (options) => {
                const step1 = !this.#hatFernkampfWaffeinHand(options)
                const step2 = !this.#hatSonderfertigkeit("Wuchtschlag", options)
                const step3 = this.#hatSonderfertigkeit("Wuchtschlag", options) && !this.#evalSonderfertigkeitRequirements("Wuchtschlag", options)
                if (step1 && (step2 || step3)) {
                    return true
                } else
                    return false
            }
        },
        {
            name: "Wuchtschlag (Sonderfertigkeit)",
            type: ActionManager.ATTACK,
            cost: ActionManager.REGULAR,
            source: ActionManager.SF,
            modDescription: "erhöht TP vom Angriff um {}",
            mod: (value) => -(value),
            activate: (queue, data) => {
                data.actor.rollAttack(data)
                return true
            },
            eval: (options) => {
                const step1 = !this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Wuchtschlag", options)
                const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Wuchtschlag", options)
                if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) {
                    return step2WithBenefits
                } else
                    return false
            }
        },
        {
            name: "Betäubungsschlag",
            type: ActionManager.ATTACK,
            cost: ActionManager.REGULAR,
            source: ActionManager.SF,
            activate: (queue, data) => {
                data.actor.rollAttack(data)
                return true
            },
            eval: (options) => {
                const step1 = !this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Betäubungsschlag", options)
                const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Betäubungsschlag", options)
                if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) {
                    return step2WithBenefits
                } else
                    return false
            }
        }
    ]

    #continuingActions = [
        {
            name: "Orientieren",
            type: ActionManager.TALENT,
            cost: ActionManager.CONTINUING,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Waffe ziehen",
            type: ActionManager.INTERACTION,
            cost: ActionManager.CONTINUING,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Sprinten",
            type: ActionManager.MOVEMENT,
            cost: ActionManager.CONTINUING,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Gegenstand benutzen",
            type: ActionManager.INTERACTION,
            cost: ActionManager.CONTINUING,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Schnellladen (Bogen)",
            type: ActionManager.INTERACTION,
            cost: ActionManager.CONTINUING,
            source: ActionManager.SF,
            cooldown: (options) => 1,
            activate: (queue) => { // find earliest Reload Action and reduce it by 1
                return true
            },
            eval: (options) => {
                const step1 = this.#hatMunition()
                    && this.#hatFernkampfWaffeinHand(options)
                && this.#hatSonderfertigkeit("Schnellladen (Bogen)", options)
                const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Schnellladen (Bogen)", options)
                if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) {
                    return step2WithBenefits
                } else
                    return false
            }
        },
        {
            name: "Schnellladen (Armbrust)",
            type: ActionManager.INTERACTION,
            cost: ActionManager.CONTINUING,
            source: ActionManager.SF,
            cooldown: (options) => 1,
            activate: (queue) => {
                return true // find earliest Reload Action and reduce it by 1
            },
            eval: (options) => {
                const step1 = this.#hatMunition()
                    && this.#hatFernkampfWaffeinHand(options)
                    && this.#hatSonderfertigkeit("Schnellladen (Armbrust)", options)
                const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Schnellladen (Armbrust)", options)
                if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) {
                    return step2WithBenefits
                } else
                    return false
            }
        },
        {
            name: "Nachladen",
            type: ActionManager.INTERACTION,
            cost: ActionManager.CONTINUING,
            source: ActionManager.DEFAULT,
            cooldown: (options) => 1, // get reload time of weapon
            activate: (queue) => {
                return true // get ammunition of actor and reduce the Qty by 1 or if its as magazine, reduce its fill by 1
            },
            eval: (options) => this.#hatMunition()
        },
        {
            name: "Talenteinsatz",
            type: ActionManager.TALENT,
            cost: ActionManager.CONTINUING,
            source: ActionManager.DEFAULT,
            eval: (options) => true
        },
        {
            name: "Zaubern",
            type: ActionManager.SPELL,
            cost: ActionManager.CONTINUING,
            source: ActionManager.SF,
            eval: (options) => this.#hatSonderfertigkeitBeginnendMit("Repräsentation:", options)
        },
        {
            name: "Liturgie wirken",
            type: ActionManager.SPELL,
            cost: ActionManager.CONTINUING,
            source: ActionManager.SF,
            eval: (options) => this.#hatSonderfertigkeitBeginnendMit("Liturgiekenntnis", options)
        }
    ]


    #hatWaffeinHand(options) {
        if (options) {
            const item = this.actor.findEquipmentOnSlot("links") ?? this.actor.findEquipmentOnSlot("rechts")
            return item == options.weapon
        } else {
            return this.actor.findEquipmentOnSlot("links") != null || this.actor.findEquipmentOnSlot("rechts") != null
        }
    }

    #hatMunition() {
        const item = this.actor.findEquipmentOnSlot("munition")
        return item != null
    }

    #hatFernkampfWaffeinHand(options) {
        if (options) {
            const item = this.actor.findEquipmentOnSlot("fernkampf")
            return item == options.weapon
        } else {
            return this.actor.findEquipmentOnSlot("fernkampf") != null
        }
    }

    #hatSonderfertigkeitBeginnendMit(name, options) {
        return this.actor.itemTypes["SpecialAbility"]?.find(p => p.name.startsWith(name)) != null
    }

    #hatSonderfertigkeit(name, options) {
        return this.actor.itemTypes["SpecialAbility"]?.find(p => p.name === name) != null
    }

    #evalSonderfertigkeitRequirements(nameOfSF, options) {
        const sf = this.actor.itemTypes["SpecialAbility"].find(p => p.name === nameOfSF)
        return sf?.system.isActive(options) ?? false
    }

    /**
     *
     * @param {{target: String?}} options
     */

    evaluate(options) {
        let actionArray = [...this.#freeActions, ...this.#regularActions, ...this.#continuingActions]
        return actionArray.filter(action => {
            return action.eval(options)
        }).map(action => {
            return {
                ...action,
                eval: action.eval(options)
            }
        })
    }

}
