import { M5Item } from "../items/M5Item"
import { M5Attributes, M5ItemMod, M5ModOperation, M5ModType, M5RollTemplate } from "../M5Base"

export class M5ItemSheet extends ItemSheet {
	
	static get defaultOptions() {
		return mergeObject(super.defaultOptions, {
			width: 640,
			height: 480,
			classes: ["midgard5", "sheet", "item"]
		})
	}

	get template() {
		//console.log("M5ItemSheet", this.item.data.type)
		const path = "systems/midgard5/templates/sheets/item"
		return `${path}/${this.item.type}.hbs`
	}

	override getData(options?: Partial<ItemSheet.Options>): ItemSheet.Data<ItemSheet.Options> | Promise<ItemSheet.Data<ItemSheet.Options>> {
		const item = this.item as M5Item
		return Promise.resolve(super.getData()).then(value => {
			item.prepareDerivedData()
			const context = value as any

			// Use a safe clone of the item data for further operations.
			const itemData = context.item

			// Retrieve the roll data for TinyMCE editors.
			context.rollData = {}
			let actor = this.object?.parent ?? null
			if (actor) {
				context.rollData = actor.getRollData() 
			}
		
			context.data = itemData.system
			context.flags = itemData.flags
		
			return context
		})
	}

	override activateListeners(html: JQuery) {
		super.activateListeners(html)

		html.find(".add-mod").on("click", async (event) => {
			const context = this.object
			const mods = context.system.mods
			const modIndex = Object.keys(mods).length
			mods[modIndex.toString()] = {
				type: M5ModType.ATTRIBUTE,
				id: M5Attributes.ST,
				operation: M5ModOperation.ADD,
				value: 0
			} as M5ItemMod
			this.object.update({
				data: {
					mods: mods
				}
			})
		})

		html.find(".item-delete").on("click", async (event) => {
			let row = event.target.parentElement
			let itemId = row.dataset["item"]
			while (!itemId) {
				row = row.parentElement
				if (!row)
					return
				itemId = row.dataset["item"]
			}

			const context = this.item
			const item = context.items.get(itemId)
			item.delete()
			this.render(false)
		})

		html.find(".roll-delete").on("click", async (event) => {
			//console.log("roll-delete", this.item.data.data.rolls.formulas)

			let row = event.target.parentElement
			let rollIndex = row.dataset["roll"]
			while (!rollIndex) {
				row = row.parentElement
				if (!row)
					return
				rollIndex = row.dataset["roll"]
			}

			const rolls = this.item.system.rolls.formulas
			rolls[rollIndex] = null

			this.item.update({
				data: {
					rolls: {
						formulas: rolls
					}
				}
			})
			this.render(false)
		})

		html.find(".roll-create").on("click", async (event) => {
			const rolls = this.item.system.rolls.formulas

			const indeces = Object.keys(rolls).map(index => parseInt(index)).sort().reverse()
			const index = (indeces.find(index => !!rolls[index.toString()]) ?? -1) + 1
			console.log("roll-create", rolls, indeces, index)

			rolls[index.toString()] = {
				formula: "1d6",
				label: (game as Game).i18n.localize("midgard5.roll"),
				enabled: true
			} as M5RollTemplate

			this.item.update({
				data: {
					rolls: {
						formulas: rolls
					}
				}
			})
			this.render(false)
		})

		// Drag & Drop
		if (["item"].includes(this.object.type)) {
			const itemToItemAssociation = new DragDrop({
				dragSelector: ".item",
				dropSelector: null,
				permissions: { dragstart: this._canDragStart.bind(this), drop: this._canDragDrop.bind(this) },
				callbacks: { drop: this._onDropItem.bind(this) },
			})
			itemToItemAssociation.bind(html[0])
		}
	}

	_canDragStart(selector) {
		console.log("M5ItemSheet._canDragStart", selector)
		return this.options.editable && this.object.isOwner
	}

	_canDragDrop(selector) {
		console.log("M5ItemSheet._canDragDrop", selector)
		return true
	}

	async _onDropItem(event) {
		let data
		const obj = this.object
		const li = event.currentTarget

		try {
			data = JSON.parse(event.dataTransfer.getData("text/plain"))
			if (data.type !== "Item")
				return false
		} catch (err) {
			return false
		}

		// Case 1 - Import from a Compendium pack
		let itemObject
		if (data.pack) {
			const compendiumObject = await (this as any).importItemFromCollection(data.pack, data.id)
			itemObject = compendiumObject.data
		}

		// Case 2 - Import from World entity
		else {
			const originalItem = await (game as Game).items.get(data.id)
			itemObject = duplicate(originalItem)
			if (!itemObject)
				return
		}

		if ((itemObject.type === "mod")) {
			let mods = obj?.system?.mods
			if (!mods)
				mods = []

			itemObject.id = randomID()
			console.log("M5ItemSheet._onDropItem", itemObject)
			mods.push(itemObject)

			obj.update({
				data: {
					mods: mods
				}
			})
		}
	}

	async _onDragItemStart(event) { }
}
