import {LiturgyData} from "../data/miracle/liturgyData.mjs";
import {Blessing} from "../documents/blessing.mjs";
import {Profession} from "../documents/profession.mjs";
import {Culture} from "../documents/culture.mjs";
import {Species} from "../documents/species.mjs";
import {SpecialAbility} from "../documents/specialAbility.mjs";
import {Equipment} from "../documents/equipment.mjs";
import {XmlImportReportDialog} from "../dialog/xmlImportReportDialog.mjs";

export class XmlImport {

    #unknownSkills = []
    #unknownSpells = []
    #unknownLiturgies = []
    #unknownItem = []
    #unknownSpecialAbilities = []
    #unknownAdvantage = []

    #ritualkenntnisse = {}

    #months = [
        "Praios",
        "Rondra",
        "Efferd",
        "Travia",
        "Boron",
        "Hesinde",
        "Firun",
        "Tsa",
        "Phex",
        "Peraine",
        "Ingerimm",
        "Rahja",
        "Namenloser Tag"
    ]

    /**
     * @typedef ImportOptions
     * @property {Boolean} skipMeta
     * @property {Boolean} skipSpecies
     * @property {Boolean} skipCulture
     * @property {Boolean} skipProfessions
     * @property {Boolean} skipAttributes
     * @property {Boolean} skipAdvantages
     * @property {Boolean} skipSpecialAbilities
     * @property {Boolean} skipEquipment
     * @property {Boolean} skipSpells
     * @property {Boolean} skipLiturgies
     * @property {Boolean} skipSkills
     **/

    static getOptions() {
        return {
            skipMeta: "Meta",
            skipSpecies: "Rasse",
            skipCulture: "Kultur",
            skipProfessions: "Professionen",
            skipAttribution: "Eigenschaften",
            skipAdvantages: "Vor und Nachteile",
            skipSpecialAbilities: "Sonderfertigkeiten",
            skipEquipment: "Inventar",
            skipSpells: "Zauber",
            skipLiturgies: "Liturgien",
            skipSkills: "Talente"
        }
    }

    /**
     * Imports a character from a file created in the tool Helden-Software
     * @param actorId the actor-id of the character
     * @param file the file from which the character should be imported
     * @param {ImportOptions?} options the set of item types the import should skip
     */
    async importCharacter(actorId, file, options = undefined) {
        let actor = game.actors.get(actorId)
        console.log("starting import with following options", options)
        let xmlString = await this.#parseFileToString(file)
        let domParser = new DOMParser()
        let dom = domParser.parseFromString(xmlString, 'application/xml')

        let rawJson = this.#getJsonFromXML(dom)

        if (!options) {
            options = {
                skipMeta: false,
                skipSpecies: false,
                skipCulture: false,
                skipProfessions: false,
                skipAttributes: false,
                skipAdvantages: false,
                skipSpecialAbilities: false,
                skipEquipment: false,
                skipSkills: false,
                skipSpells: false,
                skipLiturgies: false
            }
        }

        let characterJson = this.#mapRawJson(actor, rawJson, options)

        actor.update(characterJson)

        const sumOfAllUnknowns = this.#unknownSkills.length + this.#unknownSpells.length + this.#unknownLiturgies.length + this.#unknownItem.length + this.#unknownSpecialAbilities.length + this.#unknownAdvantage.length

        if (sumOfAllUnknowns > 0) {
            const report = []
            this.#unknownSkills.forEach( i => report.push({name: i, type: "Talent"}))
            this.#unknownSpells.forEach( i => report.push({name: i, type: "Zauber"}))
            this.#unknownLiturgies.forEach( i => report.push({name: i, type: "Liturgie"}))
            this.#unknownItem.forEach( i => report.push({name: i, type: "Gegenstand"}))
            this.#unknownSpecialAbilities.forEach( i => report.push({name: i, type: "Sonderfertigkeit"}))

            new XmlImportReportDialog(actor, report).render(true)
        }
    }


    /**
     *
     * @param dom the XML-Dom from which the json should be extracted
     * @returns {{}} the json parsed from the xml
     */
    #getJsonFromXML(dom) {
        let children = [...dom.children];

        // initializing object to be returned.
        let jsonResult = {};

        let attributes = dom.attributes ? dom.attributes : []
        for (let attribute of attributes) {
            jsonResult[attribute.name] = attribute.value
        }

        if (children.length) {
            for (let child of children) {

                // checking is child has siblings of same name.
                let childIsArray = children.filter(eachChild => eachChild.nodeName === child.nodeName).length > 1;

                // if child is array, save the values as array, else as strings.
                if (childIsArray) {
                    if (jsonResult[child.nodeName] === undefined) {
                        jsonResult[child.nodeName] = [this.#getJsonFromXML(child)];
                    } else {
                        jsonResult[child.nodeName].push(this.#getJsonFromXML(child));
                    }
                } else {
                    jsonResult[child.nodeName] = this.#getJsonFromXML(child);
                }
            }
        }

        return jsonResult;
    }

    /**
     * gets the text content of a file
     * @param file the file with the desired content
     * @returns {Promise<String>} a promise that returns the string contents of the file
     */
    async #parseFileToString(file) {
        return new Promise((resolve, reject) => {
            let reader = new FileReader()
            reader.readAsText(file, "utf-8")
            reader.onload = event => {
                resolve(event.target.result)
            }
            reader.onerror = event => {
                reject(event)
            }
        })
    }


    /**
     *Calculates a Birthdate String in the Calendar of Bosparans Fall
     * @param json json with the day, the month and the year of the birthday
     * @returns {string} a string in the format of "DD.MMMM.YYYY BF"
     */
    #calculateBirthdate(json) {
        let day = json.gbtag
        let month = this.#months[parseInt(json.gbmonat) - 1]
        let year = json.gbjahr

        return `${day}. ${month} ${year} BF`
    }


    /**
     * parses a json into a fitting character-json
     * @param {Character} actor
     * @param rawJson the json parsed from the Helden-Software XML
     * @param {ImportOptions} options
     * @returns {{}} a json representation of the character
     */
    #mapRawJson(actor, rawJson, options) {
        let json = {}
        let held = rawJson.helden.held;
        json.name = held.name
        json.meta = {}
        if (!options.skipSpecies) this.#mapSpezies(actor, held.basis.rasse) // as string includes the demonymized form
        if (!options.skipCulture) this.#mapKultur(actor, held.basis.kultur) // as string includes the demonymized form
        if (!options.skipProfessions) this.#mapProfessions(actor, held.basis.ausbildungen.ausbildung)
        if (!options.skipMeta) {
            json.meta.geschlecht = held.basis.geschlecht.name
            json.meta.haarfarbe = held.basis.rasse.aussehen.haarfarbe
            json.meta.groesse = held.basis.rasse.groesse.value.replace(",", ".") // fixes localisation
            json.meta.augenfarbe = held.basis.rasse.aussehen.augenfarbe
            json.meta.geburtstag = this.#calculateBirthdate(held.basis.rasse.aussehen)
            json.meta.alter = held.basis.rasse.aussehen.alter
            json.meta.gewicht = held.basis.rasse.groesse.gewicht
            json.meta.aussehen = [
                held.basis.rasse.aussehen.aussehentext0,
                held.basis.rasse.aussehen.aussehentext1,
                held.basis.rasse.aussehen.aussehentext2,
                held.basis.rasse.aussehen.aussehentext3].join('\n')
            json.meta.familie = [
                held.basis.rasse.aussehen.familietext0,
                held.basis.rasse.aussehen.familietext1,
                held.basis.rasse.aussehen.familietext2,
                held.basis.rasse.aussehen.familietext3,
                held.basis.rasse.aussehen.familietext4,
                held.basis.rasse.aussehen.familietext5].join('\n')
            json.meta.titel = held.basis.rasse.aussehen.titel
            json.meta.stand = held.basis.rasse.aussehen.stand
        }
        if (!options.skipAttributes) {
            let attributes = held.eigenschaften.eigenschaft
            json.attribute = {}

            if (held.basis.gilde) {
                json.attribute.gilde = held.basis.gilde.name
            }
            json.attribute.mu = this.#getAttributeJson(attributes, "Mut")
            json.attribute.kl = this.#getAttributeJson(attributes, "Klugheit")
            json.attribute.in = this.#getAttributeJson(attributes, "Intuition")
            json.attribute.ch = this.#getAttributeJson(attributes, "Charisma")
            json.attribute.ff = this.#getAttributeJson(attributes, "Fingerfertigkeit")
            json.attribute.ge = this.#getAttributeJson(attributes, "Gewandtheit")
            json.attribute.ko = this.#getAttributeJson(attributes, "Konstitution")
            json.attribute.kk = this.#getAttributeJson(attributes, "Körperkraft")
            json.mr = {
                mod: Number(this.#filterAttribute(attributes, "Magieresistenz").mod) +
                     Number(this.#filterAttribute(attributes, "Magieresistenz").value) // bought points
            }
            json.lep = {
                mod: Number(this.#filterAttribute(attributes, "Lebensenergie").mod) +
                     Number(this.#filterAttribute(attributes, "Lebensenergie").value) // bought points
            }
            json.aup = {
                mod: Number(this.#filterAttribute(attributes, "Ausdauer").mod) +
                     Number(this.#filterAttribute(attributes, "Ausdauer").value) // bought points
            }
            json.asp = {
                mod: Number(this.#filterAttribute(attributes, "Astralenergie").mod) +
                     Number(this.#filterAttribute(attributes, "Astralenergie").value) // bought points
            }
            json.kap = {
                mod: Number(this.#filterAttribute(attributes, "Karmaenergie").mod) +
                     Number(this.#filterAttribute(attributes, "Karmaenergie").value) // bought points
            }
            let attribute = this.#filterAttribute(attributes, "ini")
            json.ini = {
                mod: attribute.mod,
                aktuell: attribute.value
            }
            json.attribute.so = this.#getAttributeJson(attributes, "Sozialstatus")
        }
        if (!options.skipAdvantages) this.#mapAdvantages(actor, held)
        let specialAbilities = []
        let liturgies = []
        for (let specialAbility in held.sf.sonderfertigkeit) {
            specialAbility = held.sf.sonderfertigkeit[specialAbility]
            if (specialAbility.name.startsWith("Liturgie:")) {
                if (!options.skipLiturgies) {
                    liturgies.push({
                        name: specialAbility.name.replace("Liturgie:", "").trim(),
                    })
                }
            } else {
                if (!options.skipSpecialAbilities) {
                    let specialAbilityJson = {
                        name: specialAbility.name,
                        auswahlen: []
                    }
                    let fields = Object.keys(specialAbility)
                    if (fields.length > 1) {
                        for (let field in fields) {
                            field = fields[field]
                            if (field !== "name") {
                                let choices = specialAbility[field]
                                if (choices.hasOwnProperty("name")) {
                                    specialAbilityJson.auswahlen.push(choices.name)
                                } else {
                                    for (let choice in choices.wahl) {
                                        choice = choices.wahl[choice]
                                        specialAbilityJson.auswahlen.push(choice.value)
                                    }
                                }
                            }
                        }
                    }
                    specialAbilities.push(specialAbilityJson)
                }
            }
        }
        json.liturgien = liturgies

        let combatValues = []
        for (let combatValue in held.kampf.kampfwerte) {
            combatValue = held.kampf.kampfwerte[combatValue]
            combatValues.push({
                name: combatValue.name,
                at: combatValue.attacke.value,
                pa: combatValue.parade.value,
            })
        }
        json.kampfwerte = combatValues

        if (!options.skipSkills) this.#mapSkills(actor, held, combatValues)
        if (!options.skipSpells) this.#mapSpells(actor, held)
        if (!options.skipLiturgies) this.#mapLiturgies(actor, liturgies)
        if (!options.skipEquipment) this.#mapEquipment(actor, held)
        if (!options.skipSpecialAbilities) this.#mapSpecialAbilities(actor, specialAbilities)
        let notes = []
        for (let note in held.kommentare) {
            note = held.kommentare[note]
            if (note.hasOwnProperty("key")) {
                notes.push({
                    key: note.key,
                    notiz: note.kommentar,
                })
            }
        }
        json.notizen = notes

        return {
            name: held.name,
            system: json,
        }
    }


    /**
     * @param attributes an array with the attributes
     * @param name the name of the chosen attribute
     * @returns {{}} a representation of the chosen Attribute
     */
    #getAttributeJson(attributes, name) {
        let attribute = this.#filterAttribute(attributes, name)
        return {
            start: parseInt(attribute.value),
            aktuell: parseInt(attribute.value),
            mod: parseInt(attribute.mod),
        }
    }

    /**
     * filters a given attribute array based on the name of an attribute
     * @param attributes the attribute array
     * @param name the name of the desired attribute
     * @returns {{}} the json of the desired attribute
     */
    #filterAttribute(attributes, name) {
        return attributes.filter(attribute => attribute.name === name)[0]
    }

    async #addSkillFromCompendiumByNameToActor(talentName, taw, actor, combatStatistics, attributes) {
        const compendiumOfSkills = game.packs.get('DSA_4-1.Skills');
        const talentId = compendiumOfSkills.index.find(skill => skill.name.trim() === talentName.trim())
        if (talentId) {

            const talent = await compendiumOfSkills.getDocument(talentId._id);

            try {
                const embeddedDocument = (await actor.createEmbeddedDocuments('Item', [talent]))[0]
                if (talent.system.gruppe === "Kampf") {
                    const atbasis = attributes.find(p => p.name === "at").value
                    const pabasis = attributes.find(p => p.name === "pa").value
                    const combatStatistic = combatStatistics.find(p => p.name === talent.name)
                    if (combatStatistic) { // melee with AT/PA values
                        let at = combatStatistic.at - atbasis ?? 0
                        let pa = combatStatistic.pa - pabasis ?? 0
                        embeddedDocument.update({system: {taw, at, pa}});
                    } else { // ranged with only AT values which is equal to taw
                        embeddedDocument.update({system: {taw: taw, at: taw, pa: null}}); // at is already at raw taw and wasn't influenced by helden-software precalculations
                    }
                } else {
                    embeddedDocument.update({system: {taw: taw, at: null, pa: null}}); // just regular talent with taw
                }
            } catch (error) {
                console.error(`${talentName} not found in items`, error)
            }
        } else {
            this.#unknownSkills.push(talentName.trim())
        }
    }

    async #addAdvantageFromCompendiumByNameToActor(advantageName, advantageValue, actor, advantageComment) {
        const compendiumOfAdvantages = game.packs.get('DSA_4-1.Advantage');
        const advantageId = compendiumOfAdvantages.index.find(skill => skill.name.trim() === advantageName.trim())
        if (advantageId) {

            const advantage = await compendiumOfAdvantages.getDocument(advantageId._id);

            try {
                const embeddedDocument = (await actor.createEmbeddedDocuments('Item', [advantage]))[0]
                if (advantageComment) {
                    embeddedDocument.update({name: advantageName + " " + advantageComment, system: {name: advantageName + " " + advantageComment, value: advantageValue}})
                } else {
                    embeddedDocument.update({system: {value: advantageValue}})
                }
            } catch (error) {
                console.error(`${advantageName} not found in items`, error)
            }
        } else {
            this.#unknownAdvantage.push(advantageName.trim())
        }
    }

    async #addSpellsFromCompendiumByNameToActor(spellName, zfw, representation, hauszauber, actor) {
        const compendiumOfSpells = game.packs.get('DSA_4-1.Spells')
        const SCREAMING_NAME = spellName.toUpperCase()
        const spellId = compendiumOfSpells.index.find(spell => spell.name.trim() === SCREAMING_NAME.trim())
        if (spellId) {

            const spell = await compendiumOfSpells.getDocument(spellId._id);

            try {
                const embeddedDocument = (await actor.createEmbeddedDocuments('Item', [spell]))[0]
                embeddedDocument.update({system: {zfw: zfw, hauszauber: hauszauber}})
                embeddedDocument.setFlag("DSA_4-1", "representation", representation)
            } catch (error) {
                console.error(`${spell} not found in items`, error)
            }
        } else {
            this.#unknownSpells.push(SCREAMING_NAME.trim())
        }
    }

    async #addLiturgiesFromCompendiumByNameToActor(liturgyName, actor) {
        const compendiumOfLiturgies = game.packs.get('DSA_4-1.Liturgies');
        const liturgyId = compendiumOfLiturgies.index.find(liturgy => {
            return liturgy.name.trim() === LiturgyData.lookupAlias(liturgyName.split(" (")[0]).trim()
        })
        if (liturgyId) {

            const liturgy = await compendiumOfLiturgies.getDocument(liturgyId._id);

            try {
                await actor.createEmbeddedDocuments('Item', [liturgy])
            } catch (error) {
                console.error(`${liturgy} not found in items`, error)
            }
        } else {
            this.#unknownLiturgies.push(liturgyName.trim())
        }
    }

    #mapSkills(actor, held, kampfwerte) {
        if (actor.itemTypes["Skill"].length > 0) {
            actor.itemTypes["Skill"].forEach(s => {
                actor.items.get(s._id).delete()
            })
        }
        if (actor.itemTypes["Blessing"].length > 0) {
            actor.itemTypes["Blessing"].forEach(p => {
                actor.items.get(p._id).delete()
            })
        }
        for (let talent in held.talentliste.talent) {
            talent = held.talentliste.talent[talent]


        if (talent.name.startsWith("Ritualkenntnis")) { // hook Ritualkenntnisse
            this.#ritualkenntnisse[talent.name] =  talent.value;
        } else if (talent.name.startsWith("Liturgiekenntnis")) { // hook liturgy

                actor.createEmbeddedDocuments('Item', [
                    new Blessing({
                        name: talent.name,
                        type: "Blessing",
                        system: {
                            gottheit: new RegExp("\\((.+)\\)").exec(talent.name)[1],
                            wert: talent.value
                        }
                    })
                ])

            } else {
                // proceed
                const eigenschaften = held.eigenschaften.eigenschaft
                this.#addSkillFromCompendiumByNameToActor(talent.name, talent.value, actor, kampfwerte, eigenschaften)
            }
        }
    }

    #mapAdvantages(actor, held) {
        if (actor.itemTypes["Advantage"].length > 0) {
            actor.itemTypes["Advantage"].forEach(a => {
                actor.items.get(a._id).delete()
            })
        }
        for (let advantage in held.vt.vorteil) {
            advantage = held.vt.vorteil[advantage]
            if (advantage.value == null && advantage.auswahl) {
                advantage.value = advantage.auswahl.find(a => a["position"] === "0").value
                advantage.comment = advantage.auswahl.find(a => a["position"] === "1").value
            }
            this.#addAdvantageFromCompendiumByNameToActor(advantage.name, advantage.value, actor, advantage.comment)
        }
    }

    #mapSpells(actor, held) {
        if (actor.itemTypes["Spell"].length > 0) {
            actor.itemTypes["Spell"].forEach(s => {
                actor.items.get(s._id).delete()
            })
        }
        for (let spell in held.zauberliste.zauber) {
            spell = held.zauberliste.zauber[spell]
            this.#addSpellsFromCompendiumByNameToActor(spell.name, spell.value, spell.repraesentation, spell.hauszauber === "true", actor)
        }
    }

    #mapLiturgies(actor, liturgies) {
        if (actor.itemTypes["Liturgy"].length > 0) {
            actor.itemTypes["Liturgy"].forEach(l => {
                actor.items.get(l._id).delete()
            })
        }
        for (let liturgy in liturgies) {
            liturgy = liturgies[liturgy]
            this.#addLiturgiesFromCompendiumByNameToActor(liturgy.name, actor)
        }
    }

    #mapEquipment(actor, held) {
        if (actor.itemTypes["Equipment"].length > 0) {
            actor.itemTypes["Equipment"].forEach(e => {
                actor.items.get(e._id).delete()
            })
        }
        let i = 100
        held.gegenstände?.gegenstand?.forEach(e => {
            const compendiumOfArmor = game.packs.get('DSA_4-1.Armor');
            const compendiumOfWeapons = game.packs.get('DSA_4-1.Weapons');
            const compendiumOfAmmunition = game.packs.get('DSA_4-1.Ammunition');
            const compendiumOfItems = game.packs.get('DSA_4-1.Items');
            let eId = null
            let compendium = null
            if (compendiumOfArmor?.index.find(p => p.name === e.name)) {
                eId = compendiumOfArmor?.index.find(p => p.name === e.name)
                compendium = compendiumOfArmor
            }
            if (compendiumOfWeapons?.index.find(p => p.name === e.name)) {
                eId = compendiumOfWeapons?.index.find(p => p.name === e.name)
                compendium = compendiumOfWeapons
            }
            if (compendiumOfAmmunition?.index.find(p => p.name === e.name)) {
                eId = compendiumOfAmmunition?.index.find(p => p.name === e.name)
                compendium = compendiumOfAmmunition
            }
            if (compendiumOfItems?.index.find(p => p.name === e.name)) {
                eId = compendiumOfItems?.index.find(p => p.name === e.name)
                compendium = compendiumOfItems
            }

            if (eId && compendium) {
                compendium.getDocument(eId._id).then(sf => actor.createEmbeddedDocuments('Item', [sf]))
            } else {
                actor.createEmbeddedDocuments('Item', [new Equipment(
                    {
                        name: e.modallgemein?.name?.value ?? e.name,
                        type: "Equipment",
                        sort: (i++) * 100,
                        system: {
                            quantity: e.anzahl,
                            price: e.modallgemein?.preis.value,
                            weight: e.modallgemein?.gewicht.value,

                        }
                    })
                ])
                this.#unknownItem.push(e.modallgemein?.name?.value ?? e.name)
            }
        })
    }

    async #mapProfessions(actor, professions) {
        if (actor.itemTypes["Profession"].length > 0) {
            actor.itemTypes["Profession"].forEach(p => {
                actor.items.get(p._id).delete()
            })
        }
        if (professions.string) {
            professions = {hauptprofession: professions}
        }
        Object.values(professions).forEach(profession => {
            actor.createEmbeddedDocuments('Item', [
                new Profession({
                    name: profession.string,
                    type: "Profession",
                    system: {
                        description: "",
                        alias: profession.tarnidentitaet ? profession.tarnidentitaet : profession.string,
                        revealed: !profession.tarnidentitaet
                    }
                })
            ])
        })
    }

    async #mapSpecialAbilities(actor, specialAbilities) {
        if (actor.itemTypes["SpecialAbility"].length > 0) {
            actor.itemTypes["SpecialAbility"].forEach(s => {
                actor.items.get(s._id).delete()
            })
        }
        specialAbilities.forEach((specialAbility) => {
            const compendiumOfSF = game.packs.get('DSA_4-1.sonderfertigkeiten');
            const regexp = /(\w*)\W?(\w*)?/
            const [variantName, baseAbility, level] = regexp.exec(specialAbility.name)
            const sfId = compendiumOfSF?.index.find(sf => sf.name === baseAbility)

            if (sfId) {
                if (variantName) {
                    console.debug(baseAbility + " to be imported as " + variantName) // TODO if baseAbility already imported, adjust its level instead of adding a new embeddedDocument
                }
                compendiumOfSF.getDocument(sfId._id).then(sf => {
                    actor.createEmbeddedDocuments('Item', [sf]).then(_ => {
                        actor.itemTypes["SpecialAbility"].find(p => p.name === baseAbility).update({
                            "system.value": variantName
                        })
                    })
                })
            } else {


                if (specialAbility.name.startsWith("Ritualkenntnis")) {
                    actor.createEmbeddedDocuments('Item', [
                        new SpecialAbility({
                            name: specialAbility.name,
                            type: "SpecialAbility",
                            system: {
                                name: specialAbility.name,
                                value: specialAbility.name + "(" + this.#ritualkenntnisse[specialAbility.name] + ")",
                                description: specialAbility.auswahl?.wahl?.join("\n"),
                            }
                        })
                    ])
                } else {
                    actor.createEmbeddedDocuments('Item', [
                        new SpecialAbility({
                            name: specialAbility.name,
                            type: "SpecialAbility",
                            system: {
                                name: specialAbility.name,
                                description: specialAbility.auswahl?.wahl?.join("\n"),
                            }
                        })
                    ])
                }

                this.#unknownSpecialAbilities.push(specialAbility.name)
            }
        })

    }

    async #mapSpezies(actor, spezies) {
        if (actor.itemTypes["Species"].length > 0) {
            actor.itemTypes["Species"].forEach(s => {
                actor.items.get(s._id).delete()
            })
        }
        const compendiumOfSpecies = game.packs.get('DSA_4-1.Species');
        const speciesId = compendiumOfSpecies?.index.find(species => species.name === spezies.name)?._id

        if (speciesId) {
            const species =
                await compendiumOfSpecies.getDocument(speciesId);
            try {
                await actor.createEmbeddedDocuments('Item', [species])
            } catch (e) {
            }
        } else {
            actor.createEmbeddedDocuments('Item', [
                new Species({
                    name: spezies.name,
                    type: "Species",
                    system: {
                        feminineDemonym: spezies.string,
                        masculineDemonym: spezies.string,
                        description: "Importiert",
                    }
                })
            ])
        }

    }

    async #mapKultur(actor, kultur) {
        if (actor.itemTypes["Culture"].length > 0) {
            actor.itemTypes["Culture"].forEach(c => {
                actor.items.get(c._id).delete()
            })
        }
        const compendiumOfCultures = game.packs.get('DSA_4-1.Cultures');
        const cultureId = compendiumOfCultures?.index.find(culture => culture.name === kultur.name)?._id

        if (cultureId) {
            const culture =
                await compendiumOfCultures.getDocument(cultureId);
            try {
                await actor.createEmbeddedDocuments('Item', [culture])
            } catch (e) {
            }
        } else {
            actor.createEmbeddedDocuments('Item', [
                new Culture({
                    name: kultur.name,
                    type: "Culture",
                    system: {
                        variant: kultur.variante?.name ?? kultur.string ?? "",
                        feminineDemonym: kultur.string,
                        masculineDemonym: kultur.string,
                        description: "Importiert",
                    }
                })
            ])
        }

    }

}
