import {importCharacter} from "../xml-import/xml-import.mjs";
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
import {Zonenruestung, Zonenwunde} from "../data/Trefferzone.js";

export class Character extends Actor {

    import() {
        let input = document.createElement('input')
        input.type = 'file'
        input.accept = '.xml'
        input.onchange = e => {
            importCharacter(this.id, e.target.files[0])
        }
        input.click()
    }

    /**
     * @override
     * Augment the actor source data with additional dynamic data. Typically,
     * you'll want to handle most of your calculated/derived data in this step.
     * Data calculated in this step should generally not exist in template.json
     * (such as ability modifiers rather than ability scores) and should be
     * available both inside and outside of character sheets (such as if an actor
     * is queried and has a roll executed directly from it).
     */
    prepareDerivedData() {

        if (this.type === "character") {
            const actorData = this;
            const systemData = actorData.system;

            systemData.attribute.mu.aktuell = systemData.attribute.mu.start + systemData.attribute.mu.mod;
            systemData.attribute.kl.aktuell = systemData.attribute.kl.start + systemData.attribute.kl.mod;
            systemData.attribute.in.aktuell = systemData.attribute.in.start + systemData.attribute.in.mod;
            systemData.attribute.ch.aktuell = systemData.attribute.ch.start + systemData.attribute.ch.mod;

            systemData.attribute.ff.aktuell = systemData.attribute.ff.start + systemData.attribute.ff.mod;
            systemData.attribute.ge.aktuell = systemData.attribute.ge.start + systemData.attribute.ge.mod;
            systemData.attribute.ko.aktuell = systemData.attribute.ko.start + systemData.attribute.ko.mod;
            systemData.attribute.kk.aktuell = systemData.attribute.kk.start + systemData.attribute.kk.mod;

            const mu = systemData.attribute.mu.aktuell;
            const kl = systemData.attribute.kl.aktuell;
            const _in = systemData.attribute.in.aktuell;
            const ch = systemData.attribute.ch.aktuell;
            const ff = systemData.attribute.ff.aktuell;
            const ge = systemData.attribute.ge.aktuell;
            const ko = systemData.attribute.ko.aktuell;
            const kk = systemData.attribute.kk.aktuell;

            systemData.lep.max = Math.round((ko + ko + kk) / 2) + systemData.lep.mod;
            systemData.aup.max = Math.round((mu + ko + ge) / 2) + systemData.aup.mod;
            systemData.asp.max = Math.round((mu + _in + ch) / 2) + systemData.asp.mod;


            systemData.at = systemData.at ?? {links: {}, rechts: {}}
            systemData.at.links = systemData.at.links ?? {
                aktuell: 0,
                mods: 0
            }
            systemData.at.rechts = systemData.at.rechts ?? {
                aktuell: 0,
                mods: 0
            }
            systemData.at.basis = Math.round((mu + ge + kk) / 5)
            systemData.at.aktuell = systemData.at.basis + (systemData.at.mod ?? 0);
            systemData.at.links.aktuell = systemData.at.basis + (systemData.at.links.mod ?? 0);
            systemData.at.rechts.aktuell = systemData.at.basis + (systemData.at.rechts.mod ?? 0);
            systemData.pa = systemData.pa ?? {links: {}, rechts: {}}
            systemData.pa.links = systemData.pa.links ?? {
                aktuell: 0,
                mods: 0
            }
            systemData.pa.rechts = systemData.pa.rechts ?? {
                aktuell: 0,
                mods: 0
            }
            systemData.pa.basis = Math.round((_in + ge + kk) / 5);
            systemData.pa.aktuell = systemData.pa.basis + (systemData.pa.mod ?? 0);
            systemData.pa.links.aktuell = systemData.pa.basis + (systemData.pa.links.mod ?? 0);
            systemData.pa.rechts.aktuell = systemData.pa.basis + (systemData.pa.links.mod ?? 0);
            systemData.fk = systemData.fk ?? {
                aktuell: 0,
                mods: 0
            }
            systemData.fk.basis = Math.round((_in + ff + kk) / 5);
            systemData.fk.aktuell = systemData.fk.basis + (systemData.fk.mod ?? 0);

            systemData.ini.basis = Math.round((mu + mu + _in + ge) / 5)
            systemData.ini.aktuell = systemData.ini.basis + (systemData.ini.mod ?? 0);
            systemData.mr.basis = Math.round((mu + kl + ko) / 5)
            systemData.mr.aktuell = systemData.mr.basis + (systemData.mr.mod ?? 0);
            systemData.gs.basis = 6;
            systemData.gs.aktuell = systemData.gs.basis + (systemData.gs.mod ?? 0); // TOOD: get GS from species


            if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
                systemData.rs = {
                    brust: 0,
                    bauch: 0,
                    armlinks: 0,
                    armrechts: 0,
                    beinlinks: 0,
                    beinrechts: 0,
                    kopf: 0,
                }; // only with DSA_4-1.optional_trefferzonen = true
            } else {
                systemData.rs = 0; // only with DSA_4-1.optional_trefferzonen = false
            }
            systemData.be = 0;


            // half KO is the maximum a character can sustain wounds before collapsing
            systemData.wunden.max = ko / 2;
            if (game.settings.get("DSA_4-1", "optional_trefferzonen")) {
                systemData.wunden.kopf = 0;
                systemData.wunden.brust = 0;
                systemData.wunden.bauch = 0;
                systemData.wunden.armlinks = 0;
                systemData.wunden.armrechts = 0;
                systemData.wunden.beinlinks = 0;
                systemData.wunden.beinrechts = 0;
            }

            systemData.ws = ko / 2;

            // map current set to RS and BE

            const ausruestung = systemData.heldenausruestung[systemData.setEquipped];
            if (ausruestung) {
                if (ausruestung.brust) {
                    systemData.be += systemData.parent.items.get(ausruestung.brust).system.armorHandicap ?? 0
                    if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
                        systemData.rs.brust = systemData.parent.items.get(ausruestung.brust).system.armorValue ?? 0
                    } else {
                        systemData.rs += systemData.parent.items.get(ausruestung.brust).system.armorValue ?? 0
                    }
                }
                if (ausruestung.bauch) {
                    systemData.be += systemData.parent.items.get(ausruestung.bauch).system.armorHandicap ?? 0
                    if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
                        systemData.rs.bauch = systemData.parent.items.get(ausruestung.bauch).system.armorValue ?? 0
                    } else {
                        systemData.rs += systemData.parent.items.get(ausruestung.bauch).system.armorValue ?? 0
                    }
                }
                if (ausruestung.ruecken) {
                    systemData.be += systemData.parent.items.get(ausruestung.ruecken).system.armorHandicap ?? 0
                    if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
                        // ruecken is not a valid trefferzone
                    } else {
                        systemData.rs += systemData.parent.items.get(ausruestung.ruecken).system.armorValue ?? 0
                    }
                }
                if (ausruestung.armlinks) {
                    systemData.be += systemData.parent.items.get(ausruestung.armlinks).system.armorHandicap ?? 0
                    if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
                        systemData.rs.armlinks = systemData.parent.items.get(ausruestung.armlinks).system.armorValue ?? 0
                    } else {
                        systemData.rs += systemData.parent.items.get(ausruestung.armlinks).system.armorValue ?? 0
                    }
                }
                if (ausruestung.armrechts) {
                    systemData.be += systemData.parent.items.get(ausruestung.armrechts).system.armorHandicap ?? 0
                    if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
                        systemData.rs.armrechts = systemData.parent.items.get(ausruestung.armrechts).system.armorValue ?? 0
                    } else {
                        systemData.rs += systemData.parent.items.get(ausruestung.armrechts).system.armorValue ?? 0
                    }
                }
                if (ausruestung.beinlinks) {
                    systemData.be += systemData.parent.items.get(ausruestung.beinlinks).system.armorHandicap ?? 0
                    if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
                        systemData.rs.beinlinks = systemData.parent.items.get(ausruestung.beinlinks).system.armorValue ?? 0
                    } else {
                        systemData.rs += systemData.parent.items.get(ausruestung.beinlinks).system.armorValue ?? 0
                    }
                }
                if (ausruestung.beinrechts) {
                    systemData.be += systemData.parent.items.get(ausruestung.beinrechts).system.armorHandicap ?? 0
                    if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
                        systemData.rs.beinrechts = systemData.parent.items.get(ausruestung.beinrechts).system.armorValue ?? 0
                    } else {
                        systemData.rs += systemData.parent.items.get(ausruestung.beinrechts).system.armorValue ?? 0
                    }
                }
                if (ausruestung.kopf) {
                    systemData.be += systemData.parent.items.get(ausruestung.kopf).system.armorHandicap ?? 0
                    if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
                        systemData.rs.kopf = systemData.parent.items.get(ausruestung.kopf).system.armorValue ?? 0
                    } else {
                        systemData.rs += systemData.parent.items.get(ausruestung.kopf).system.armorValue ?? 0
                    }
                }
            }


            systemData.kap.max = 0;

            // evaluate deities for KaP

            const deities = systemData.parent.items.filter(p => p.type === "Blessing")
            deities?.forEach((deity) => {
                if (LiturgyData.alverans.includes(deity.system.gottheit)) {
                    systemData.kap.max = 24;
                } else if (systemData.kap.max === 0) {
                    systemData.kap.max += 12;
                }
            }, 0)

        }


    }

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

    getRollData() {
        const data = super.getRollData();

        if (this.type !== 'character' && this.type !== 'creature') return;

        if (data.attribute) {
            for (let [k, v] of Object.entries(data.attribute)) {
                data[k] = foundry.utils.deepClone(v);
            }
        }

        // move sonderfertigkeiten into data, if it isn't in data the actor doesn't have that sonderfertigkeit

        data.sf = {}
        if (data.sonderfertigkeiten) {
            data.sonderfertigkeiten.forEach(sf => {
                data.sf[sf.name] = sf.auswahl;
            })
            delete data.sonderfertigkeiten;
        }

        return data;
    }

    /**
     *
     * @param amount
     * @param zone either null or one of
     * @returns {Promise<void>}
     */
    async takeDamage(amount = null, zone = null) {

        this.prepareDerivedData()

        const playWithZoneArmor = game.settings.get("DSA_4-1", "optional_ruestungzonen")
        const playWithWoundZones = game.settings.get("DSA_4-1", "optional_trefferzonen")
        const previousLeP = this.system.lep.aktuell;

        if (amount == null) {
            // TODO show Dialog for entering damage amount (TP)
        }

        let armorReduction = 0
        let setEquipped = this.system.setEquipped
        let woundThreshold = this.system.ws

        if (playWithZoneArmor) {
            const armorId = this.system.heldenausruestung[setEquipped][Zonenruestung[zone]]
            const zoneArmor = await this.items.find(p => p._id === armorId)
            if (!zoneArmor) {
                return console.error(`zone "${zone}" is not a valid value`)
            }
            armorReduction = zoneArmor.system.armorValue ?? 0
        } else {
            armorReduction = this.system.rs
        }

        let damage = amount - armorReduction
        let wounds = damage / woundThreshold

        let wound = null

        if (playWithWoundZones) {
            wound = await game.packs.get("DSA_4-1.Wounds").index.find(p => p.name === Zonenwunde[zone])
            if (!wound) {
                return console.error(`Wunden Dokument zu "${zone}" konnten nicht gefunden werden`)
            }
        } else {
            wound = await game.packs.get("DSA_4-1.Wounds").index.find(p => p.name === Wunde)
            if (!wound) {
                return console.error(`Wunden Dokument zu "${Wunde}" konnten nicht gefunden werden`)
            }
        }

        // TODO this doesnt work yet, wound documents wont get expanded

        for (let i = 0; i < wounds; i++) {
            await this.createEmbeddedDocuments('Item', [wound])
        }
        await this.update({system: {lep: {aktuell: previousLeP - damage}}})
    }
}
