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

class EquipmentSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {

    /** @inheritDoc */
    static DEFAULT_OPTIONS = {
        position: {width: 640, height: 480},
        classes: ['dsa41', 'sheet', 'item', 'equipment'],
        tag: 'form',
        form: {
            submitOnChange: true,
            closeOnSubmit: false,
            handler: EquipmentSheet.#onSubmitForm
        },
        window: {
            resizable: true,
        },
        actions: {
            editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
            addToMelee: EquipmentSheet.#addToMelee,
            removeFromMelee: EquipmentSheet.#removeFromMelee,
            addToRanged: EquipmentSheet.#addToRanged,
            removeFromRanged: EquipmentSheet.#removeFromRanged
        }
    }

    static TABS = {
        sheet: {
            tabs: [
                {id: 'meta', group: 'sheet', label: 'Meta'},
                // Additional Tabs are added based on the nature of this item

            ],
            initial: 'meta'
        }
    }


    /** @inheritDoc */
    static PARTS = {
        form: {
            template: `systems/DSA_4-1/templates/item/equipment/main-sheet.hbs`
        },
        meta: {
            template: `systems/DSA_4-1/templates/item/equipment/tab-meta.hbs`
        },
        melee: {
            template: `systems/DSA_4-1/templates/item/equipment/tab-melee.hbs`
        },
        ranged: {
            template: `systems/DSA_4-1/templates/item/equipment/tab-ranged.hbs`
        },
        ammunition: {
            template: `systems/DSA_4-1/templates/item/equipment/tab-ammunition.hbs`
        },
        currency: {
            template: 'systems/DSA_4-1/templates/item/equipment/tab-currency.hbs'
        },
        armor: {
            template: `systems/DSA_4-1/templates/item/equipment/tab-armor.hbs`
        },
        settings: {
            template: `systems/DSA_4-1/templates/item/equipment/tab-settings.hbs`
        },

    }

    _configureRenderOptions(options) {
        super._configureRenderOptions(options)

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

        return options
    }

    static async #addToMelee(event, target) {
        const optionId = this.element.querySelector(`[data-target-field="${target.dataset.targetField}"]`).value
        const meleeSkills = this.document.system.meleeSkills
        if (optionId.trim() !== '' && !meleeSkills.includes(optionId)) {
            meleeSkills.push(optionId)
            await this.document.update({'system.meleeSkills': meleeSkills})
        }
    }

    static async #removeFromMelee(event, target) {
        const {optionId} = target.dataset
        let meleeSkills = this.document.system.meleeSkills
        meleeSkills = meleeSkills.toSpliced(meleeSkills.indexOf(optionId), 1)
        await this.document.update({'system.meleeSkills': meleeSkills})
    }

    static async #addToRanged(event, target) {
        const optionId = this.element.querySelector(`[data-target-field="${target.dataset.targetField}"]`).value
        const rangedSkills = this.document.system.rangedSkills
        if (optionId.trim() !== '' && !rangedSkills.includes(optionId)) {
            rangedSkills.push(optionId)
            await this.document.update({'system.rangedSkills': rangedSkills})
        }
    }

    static async #removeFromRanged(event, target) {
        const {optionId} = target.dataset
        let rangedSkills = this.document.system.rangedSkills
        rangedSkills = rangedSkills.toSpliced(rangedSkills.indexOf(optionId), 1)
        await this.document.update({'system.rangedSkills': rangedSkills})
    }

    /**
     * Handle form submission
     * @this {EquipmentSheet}
     * @param {SubmitEvent} event
     * @param {HTMLFormElement} form
     * @param {FormDataExtended} formData
     */
    static async #onSubmitForm(event, form, formData) {
        event.preventDefault()

        let normalisedFormData = {}

        Object.entries(formData.object).forEach(([key, value]) => {
            if (Array.isArray(value)) {
                normalisedFormData[key] = value[0]
            } else {
                normalisedFormData[key] = value
            }
        })

        // manage categories into array
        normalisedFormData['system.category'] = []
        if (normalisedFormData.isMelee) normalisedFormData['system.category'].push("Nahkampfwaffe")
        delete normalisedFormData.isMelee
        if (normalisedFormData.isRanged) normalisedFormData['system.category'].push("Fernkampfwaffe")
        delete normalisedFormData.isRanged
        if (normalisedFormData.isAmmunition) normalisedFormData['system.category'].push("Munition")
        delete normalisedFormData.isAmmunition
        if (normalisedFormData.isArmor) normalisedFormData['system.category'].push("Rüstung")
        delete normalisedFormData.isArmor
        if (normalisedFormData.isCurrency) normalisedFormData['system.category'].push("Währung")
        delete normalisedFormData.isCurrency

        await this.document.update(normalisedFormData) // Note: formData.object
    }

    async _preparePartContext(partId, context) {
        switch (partId) {
            case 'meta':
                this.#prepareMetaContext(context)
                break;
            case 'melee':
                this.#prepareMeleeContext(context)
                break;
            case 'ranged':
                this.#prepareRangedContext(context)
                break;
            case 'armor':
                this.#prepareArmorContext(context)
                break;
            case 'ammunition':
                this.#prepareAmmunitionContext(context)
                break;
            case 'currency':
                this.#prepareCurrencyContext(context)
                break;
            case 'settings':
                this.#prepareSettingsContext(context)
                break;
        }
        context.tab = context.tabs[partId]
        return context
    }

    #prepareMetaContext(context) {
        const equipmentData = context.document.system
        context.system = equipmentData
        context.quantity = equipmentData.quantity
        context.description = equipmentData.description
        context.name = context.document.name
        context.img = context.document.img

        context.categoryAndOptions = {
            options: {
                Gegenstand: "Gegenstand",
                Nahkampfwaffe: "Nahkampfwaffe",
                Fernkampfwaffe: "Fernkampfwaffe",
                Behälter: "Behälter",
            },
            entries: equipmentData.category,
            targetField: "category"
        };
    }

    #prepareMeleeContext(context) {
        const equipmentData = context.document.system
        context.system = equipmentData
        context.meleeSkillsAndOptions = {
            options: {
                "": "",
                Dolche: "Dolche",
                Fechtwaffen: "Fechtwaffen",
                "Säbel": "Säbel",
                Schwerter: "Schwerter",
                "Anderthalbhänder": "Anderthalbhänder",
                "Zweihandschwerter/-säbel": "Zweihandschwerter/-säbel",
                "Infanteriewaffen": "Infanteriewaffen",
                "Speere": "Speere",
                "Stäbe": "Stäbe",
                "Hiebwaffen": "Hiebwaffen",
                "Zweihand-Hiebwaffen": "Zweihand-Hiebwaffen",
                "Kettenwaffen": "Kettenwaffen",
                "Raufen": "Raufen"
            },
            entries: equipmentData.meleeSkills,
            targetField: "meleeSkills",
            removeOption: "removeFromMelee",
            addOption: "addToMelee",
        }
    }

    #prepareRangedContext(context) {
        const equipmentData = context.document.system
        context.rangedSkillsAndOptions = {
            options: {
                "": "",
                "Wurfmesser": "Wurfmesser",
                "Wurfspeer": "Wurfspeer",
                "Wurfbeil": "Wurfbeil",
                "Armbrust": "Armbrust",
                "Bogen": "Bogen",
            },
            entries: equipmentData.rangedSkills,
            targetField: "rangedSkills",
            removeOption: "removeFromRanged",
            addOption: "addToRanged",
        }
    }

    #prepareAmmunitionContext(context) {

    }

    #prepareArmorContext(context) {

    }

    #prepareCurrencyContext(context) {

    }

    #prepareSettingsContext(context) {
        context.isMelee = this.document.system.category.includes("Nahkampfwaffe")
        context.isRanged = this.document.system.category.includes("Fernkampfwaffe")
        context.isAmmunition = this.document.system.category.includes("Munition")
        context.isArmor = this.document.system.category.includes("Rüstung")
        context.isCurrency = this.document.system.category.includes("Währung")
    }

    /**
     * Adds Tabs based on the items nature
     *
     * @param {String} group
     * @private
     */
    _getTabsConfig(group) {

        const tabs = foundry.utils.deepClone(super._getTabsConfig(group))

        const category = this.document.system.category
        /**
         *
         * @type {[{ApplicationTab}]}
         */

        if (category.includes("Nahkampfwaffe")) {
            tabs.tabs.push({
                id: 'melee', group: group, label: 'Nahkampfwaffe'
            })
        }
        if (category.includes("Fernkampfwaffe")) {
            tabs.tabs.push({
                id: 'ranged', group: group, label: 'Fernkampfwaffe'
            })
        }
        if (category.includes("Rüstung")) {
            tabs.tabs.push({
                id: 'armor', group: group, label: 'Rüstung'
            })
        }
        if (category.includes("Währung")) {
            tabs.tabs.push({
                id: 'currency', group: group, label: 'Währung'
            })
        }

        tabs.tabs.push({
            id: 'settings', group: group, label: 'Einstellungen'
        })

        return tabs
    }

    /** @override */
    async _prepareContext(options) {

        const context = await super._prepareContext(options)
        context.price = context.document.system.price
        context.weight = context.document.system.weight
        context.inventoryItems = []
        context.containerVolume = context.document.system.containerVolume

        return context
    }

    /**
     * Actions performed after any render of the Application.
     * Post-render steps are not awaited by the render process.
     * @param {ApplicationRenderContext} context      Prepared context data
     * @param {RenderOptions} options                 Provided render options
     * @protected
     */
    _onRender(context, options) {

        new foundry.applications.ux.DragDrop.implementation({
            dropSelector: ".inventory-table",
            permissions: {
                drop: this._canDragDrop.bind(this)
            },
            callbacks: {
                drop: this._onDrop.bind(this)
            }
        }).bind(this.element);
    }

    _canDragDrop(event) {
        return true
    }

    async _onDrop(event) {
        const data = TextEditor.implementation.getDragEventData(event);

        // Dropped Documents
        const documentClass = foundry.utils.getDocumentClass(data.type);
        if (documentClass) {

            const document = await documentClass.fromDropData(data)
            // Dropped Documents
            document.update({"parent": this.document})
        }
    }

}

export default EquipmentSheet
