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

export class CreatureSheet extends HandlebarsApplicationMixin(ActorSheetV2) {

    /** @inheritDoc */
    static DEFAULT_OPTIONS = {
        position: {width: 520, height: 480},
        classes: ['dsa41', 'sheet', 'actor', 'creature'],
        tag: 'form',
        form: {
            submitOnChange: true,
            closeOnSubmit: false,
            handler: CreatureSheet.#onSubmitForm
        },
        actions: {
            openEmbeddedDocument: CreatureSheet.#openEmbeddedDocument,
            removeAttack: CreatureSheet.#removeAttack,
            addAttack: CreatureSheet.#addAttack,
            roll: CreatureSheet.#dieRoll,
            editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
        }
    }

    static TABS = {
        sheet: {
            tabs: [],
        }
    }

    /** @inheritDoc */
    static PARTS = {
        form: {
            template: `systems/DSA_4-1/templates/actor/creature/main-sheet.hbs`
        },
        meta: {
            template: `systems/DSA_4-1/templates/actor/creature/tab-meta.hbs`
        },
        attacks: {
            template: `systems/DSA_4-1/templates/actor/creature/tab-attacks.hbs`
        },
        description: {
            template: `systems/DSA_4-1/templates/actor/creature/tab-description.hbs`
        },
        loot: {
            template: `systems/DSA_4-1/templates/actor/creature/tab-loot.hbs`
        },
        visibility: {
            template: `systems/DSA_4-1/templates/actor/creature/tab-visibility.hbs`
        },
    }

    _getTabsConfig(group) {
        const tabs = foundry.utils.deepClone(super._getTabsConfig(group))
        const tabDef = [
            {id: 'meta', group: 'sheet', label: 'Meta'},
            {id: 'attacks', group: 'sheet', label: 'Attacken'},
            {id: 'description', group: 'sheet', label: 'Beschreibung'},
            {id: 'loot', group: 'sheet', label: 'Loot'},
            {id: 'visibility', group: 'sheet', label: 'Sichtbarkeit'},
        ]

        for (const tab of tabDef) {
            if (game.user.isGM || this.document.system.visibility[tab.id]) {
                tabs.tabs.push(tab)
            }
        }

        if (!game.user.isGM) {
            if (this.document.system.visibility.meta) {
                tabs.initial = 'meta'
            } else if (this.document.system.visibility.attacks) {
                tabs.initial = 'attacks'
            } else if (this.document.system.visibility.description) {
                tabs.initial = 'description'
            } else if (this.document.system.visibility.loot) {
                tabs.initial = 'loot'
            }
        }

        return tabs
    }

    _configureRenderOptions(options) {
        super._configureRenderOptions(options)

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

        return options
    }

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

        await this.document.update(formData.object)
    }

    static #openEmbeddedDocument(event, target) {
        const dataset = target.dataset
        const id = dataset.itemId ?? dataset.id
        this.document.items.get(id).sheet.render(true)
    }

    static async #removeAttack(evt) {
        const {index} = evt.srcElement.dataset;
        let sans = Array.from(this.document.system.attacks)
        sans.splice(index, 1)
        await this.document.update({'system.attacks': sans})
    }

    static async #dieRoll(evt) {
        const {rollType, rollName, roll} = evt.srcElement.dataset;
        let r = new Roll(roll, this.document.getRollData());
        const label = `${rollType} (${rollName})`
        await r.toMessage({
            speaker: ChatMessage.getSpeaker({actor: this.document}),
            flavor: label,
            rollMode: game.settings.get('core', 'rollMode'),
        })
    }

    static async #addAttack() {
        const name = this.element.querySelector('#attack_name').value
        const at = this.element.querySelector('#attack_at').value
        const pa = this.element.querySelector('#attack_pa').value
        const tp = this.element.querySelector('#attack_tp').value

        const newAttack = {
            name,
            at,
            pa,
            tp
        }

        await this.document.update({'system.attacks': [...this.document.system.attacks, newAttack]})

        this.element.querySelector('#attack_name').value = ""
        this.element.querySelector('#attack_at').value = ""
        this.element.querySelector('#attack_pa').value = ""
        this.element.querySelector('#attack_tp').value = ""
    }

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

        const context = await super._prepareContext(options)
        const actorData = context.document

        context.attacks = []
        context.actor = actorData

        actorData.system.attacks.forEach((attack, index) => {
            context.attacks.push({
                namepath: `system.attacks.${index}.name`,
                name: attack.name,
                atpath: `system.attacks.${index}.at`,
                at: attack.at,
                papath: `system.attacks.${index}.pa`,
                pa: attack.pa,
                tppath: `system.attacks.${index}.tp`,
                tp: attack.tp,
                index: index,

            })
        })

        context.metaRevealed = actorData.system.visibility.meta
        context.attacksRevealed = actorData.system.visibility.attacks
        context.descriptionRevealed = actorData.system.visibility.description
        context.lootRevealed = actorData.system.visibility.loot
        context.inventoryItems = []

        actorData.items.forEach((item, index) => {
            if (item.type === "Equipment") {
                context.inventoryItems.push({
                    index: index,
                    id: item._id,
                    quantity: item.system.quantity,
                    name: item.name,
                    icon: item.img
                })
            }
        })


        return context
    }


    _canDragDrop(event, options) {
        return game.user.isGM
    }

    _canDrag(event, options) {
        return true
    }

    async _onDrop(event) {

        const data = TextEditor.implementation.getDragEventData(event);
        const actor = this.actor;
        //const allowed = Hooks.call("dropActorSheetData", actor, this, data);
        // if (allowed === false) return;
        // Dropped Documents
        const documentClass = foundry.utils.getDocumentClass(data.type)
        if (documentClass) {
            const document = await documentClass.fromDropData(data);

            if (document.type === "Equipment") {
                // No duplication by moving items from one actor to another
                if (document.parent && document.parent !== this.actor) {
                    document.parent.items.get(document._id).delete()
                }

                await this._onDropDocument(event, document)
            }
        }
    }

    _onRender(context, options) {
        new foundry.applications.ux.DragDrop.implementation({
            dropSelector: ".window-content",
            dragSelector: ".equipment",
            permissions: {
                drop: this._canDragDrop.bind(this),
                drag: this._canDrag.bind(this)
            },
            callbacks: {
                dragstart: this._onDragStart.bind(this),
                drop: this._onDrop.bind(this)
            }
        }).bind(this.element)

    }

}
