const { HandlebarsApplicationMixin } = foundry.applications.api

export default class HawkmoonItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {
  constructor(options = {}) {
    super(options)
    this.#dragDrop = this.#createDragDropHandlers()
  }

  #dragDrop

  /** @override */
  static DEFAULT_OPTIONS = {
    classes: ["fvtt-hawkmoon-cyd", "item"],
    position: {
      width: 620,
      height: 600,
    },
    form: {
      submitOnChange: true,
    },
    window: {
      resizable: true,
    },
    tabs: [
      {
        navSelector: 'nav[data-group="primary"]',
        contentSelector: "section.sheet-body",
        initial: "description",
      },
    ],
    dragDrop: [{ dragSelector: "[data-drag]", dropSelector: null }],
    actions: {
      editImage: HawkmoonItemSheet.#onEditImage,
      postItem: HawkmoonItemSheet.#onPostItem,
      addPredilection: HawkmoonItemSheet.#onAddPredilection,
      deletePredilection: HawkmoonItemSheet.#onDeletePredilection,
      addAutomation: HawkmoonItemSheet.#onAddAutomation,
      deleteAutomation: HawkmoonItemSheet.#onDeleteAutomation,
    },
  }

  /**
   * Tab groups state
   * @type {object}
   */
  tabGroups = { primary: "description" }

  /**
   * Is the sheet currently in 'Play' mode?
   * @type {boolean}
   */
  /** @override */
  async _prepareContext() {
    const context = {
      fields: this.document.schema.fields,
      systemFields: this.document.system.schema.fields,
      item: this.document,
      system: this.document.system,
      source: this.document.toObject(),
      enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }),
      isEditMode: true,
      isEditable: this.isEditable,
      isGM: game.user.isGM,
      config: CONFIG.HAWKMOON,
      attributs: this.#getAttributs(),
    }
    return context
  }

  /** @override */
  _onRender(context, options) {
    super._onRender(context, options)
    this.#dragDrop.forEach((d) => d.bind(this.element))

    // Activate tab navigation manually
    const nav = this.element.querySelector('nav.tabs[data-group]')
    if (nav) {
      const group = nav.dataset.group
      // Activate the current tab
      const activeTab = this.tabGroups[group] || "description"
      nav.querySelectorAll('[data-tab]').forEach(link => {
        const tab = link.dataset.tab
        link.classList.toggle('active', tab === activeTab)
        link.addEventListener('click', (event) => {
          event.preventDefault()
          this.tabGroups[group] = tab
          this.render()
        })
      })

      // Show/hide tab content
      this.element.querySelectorAll('[data-group="' + group + '"][data-tab]').forEach(content => {
        content.classList.toggle('active', content.dataset.tab === activeTab)
      })
    }
  }

  // #region Drag-and-Drop Workflow
  /**
   * Create drag-and-drop workflow handlers for this Application
   * @returns {DragDrop[]}     An array of DragDrop handlers
   * @private
   */
  #createDragDropHandlers() {
    return this.options.dragDrop.map((d) => {
      d.permissions = {
        dragstart: this._canDragStart.bind(this),
        drop: this._canDragDrop.bind(this),
      }
      d.callbacks = {
        dragstart: this._onDragStart.bind(this),
        dragover: this._onDragOver.bind(this),
        drop: this._onDrop.bind(this),
      }
      return new foundry.applications.ux.DragDrop.implementation(d)
    })
  }

  /**
   * Can the User start a drag workflow for a given drag selector?
   * @param {string} selector       The candidate HTML selector for the drag event
   * @returns {boolean}             Can the current user drag this selector?
   * @protected
   */
  _canDragStart(selector) {
    return this.isEditable
  }

  /**
   * Can the User drop an entry at a given drop selector?
   * @param {string} selector       The candidate HTML selector for the drop event
   * @returns {boolean}             Can the current user drop on this selector?
   * @protected
   */
  _canDragDrop(selector) {
    return this.isEditable
  }

  /**
   * Callback for dragstart events.
   * @param {DragEvent} event       The drag start event
   * @protected
   */
  _onDragStart(event) {
    const target = event.currentTarget
    const dragData = { type: "Item", uuid: this.document.uuid }
    event.dataTransfer.setData("text/plain", JSON.stringify(dragData))
  }

  /**
   * Callback for dragover events.
   * @param {DragEvent} event       The drag over event
   * @protected
   */
  _onDragOver(event) {
    // Default behavior is fine
  }

  /**
   * Callback for drop events.
   * @param {DragEvent} event       The drop event
   * @protected
   */
  async _onDrop(event) {
    const data = TextEditor.getDragEventData(event)
    const item = await fromUuid(data.uuid)
    if (!item) return

    // Handle drop logic here if needed
    console.log("Item dropped:", item)
  }
  // #endregion

  // #region Action Handlers
  /**
   * Edit the item image
   * @param {Event} event       The triggering event
   * @param {HTMLElement} target    The target element
   * @private
   */
  static async #onEditImage(event, target) {
    const fp = new foundry.applications.ui.FilePicker({
      type: "image",
      current: this.document.img,
      callback: (path) => {
        this.document.update({ img: path })
      },
    })
    return fp.browse()
  }

  /**
   * Post item to chat
   * @param {Event} event       The triggering event
   * @param {HTMLElement} target    The target element
   * @private
   */
  static async #onPostItem(event, target) {
    let chatData = foundry.utils.duplicate(this.document)
    if (this.document.actor) {
      chatData.actor = { id: this.document.actor.id }
    }
    // Don't post any image for the item if the default image is used
    if (chatData.img.includes("/blank.png")) {
      chatData.img = null
    }
    // JSON object for easy creation
    chatData.jsondata = JSON.stringify({
      compendium: "postedItem",
      payload: chatData,
    })

    const html = await renderTemplate('systems/fvtt-hawkmoon-cyd/templates/post-item.hbs', chatData)
    const chatOptions = {
      user: game.user.id,
      content: html,
    }
    ChatMessage.create(chatOptions)
  }

  /**
   * Add a predilection
   * @param {Event} event       The triggering event
   * @param {HTMLElement} target    The target element
   * @private
   */
  static async #onAddPredilection(event, target) {
    let pred = foundry.utils.duplicate(this.document.system.predilections || [])
    pred.push({ name: "Nouvelle prédilection", id: foundry.utils.randomID(16), used: false, acquise: false, maitrise: false, description: "" })
    await this.document.update({ 'system.predilections': pred })
  }

  /**
   * Delete a predilection
   * @param {Event} event       The triggering event
   * @param {HTMLElement} target    The target element
   * @private
   */
  static async #onDeletePredilection(event, target) {
    const index = parseInt(target.closest("[data-predilection-index]").dataset.predilectionIndex)
    let pred = foundry.utils.duplicate(this.document.system.predilections)
    pred.splice(index, 1)
    await this.document.update({ 'system.predilections': pred })
  }

  /**
   * Add an automation
   * @param {Event} event       The triggering event
   * @param {HTMLElement} target    The target element
   * @private
   */
  static async #onAddAutomation(event, target) {
    let autom = foundry.utils.duplicate(this.document.system.automations || [])
    autom.push({
      eventtype: "on-drop",
      name: "Automatisation 1",
      bonusname: "vigueur",
      bonus: 0,
      competence: "",
      minLevel: 0,
      baCost: 0,
      id: foundry.utils.randomID(16)
    })
    await this.document.update({ 'system.automations': autom })
  }

  /**
   * Delete an automation
   * @param {Event} event       The triggering event
   * @param {HTMLElement} target    The target element
   * @private
   */
  static async #onDeleteAutomation(event, target) {
    const index = parseInt(target.closest("[data-automation-index]").dataset.automationIndex)
    let autom = foundry.utils.duplicate(this.document.system.automations)
    autom.splice(index, 1)
    await this.document.update({ 'system.automations': autom })
  }
  // #endregion

  // #region Helper Methods
  /**
   * Get list of attributs
   * @returns {Object}
   * @private
   */
  #getAttributs() {
    return {
      "adr": "Adresse",
      "pui": "Puissance",
      "cla": "Clairvoyance",
      "pre": "Présence",
      "tre": "Trempe"
    }
  }
  // #endregion

  /** @override */
  _onChangeForm(formConfig, event) {
    // Handle special form changes
    const target = event.target

    // Handle predilection field changes
    if (target.classList.contains('edit-predilection') ||
      target.classList.contains('edit-predilection-description') ||
      target.classList.contains('predilection-acquise') ||
      target.classList.contains('predilection-maitrise') ||
      target.classList.contains('predilection-used')) {
      const li = target.closest('.prediction-item')
      if (li) {
        const index = parseInt(li.dataset.predictionIndex)
        const field = target.classList.contains('edit-predilection') ? 'name' :
          target.classList.contains('edit-predilection-description') ? 'description' :
            target.classList.contains('predilection-acquise') ? 'acquise' :
              target.classList.contains('predilection-maitrise') ? 'maitrise' : 'used'

        let pred = foundry.utils.duplicate(this.document.system.predilections)
        if (target.type === 'checkbox') {
          pred[index][field] = target.checked
        } else {
          pred[index][field] = target.value
        }
        pred[index].id = pred[index].id || foundry.utils.randomID(16)
        this.document.update({ 'system.predilections': pred })
        return
      }
    }

    // Handle automation field changes
    if (target.classList.contains('automation-edit-field')) {
      const index = parseInt(target.dataset.automationIndex)
      const field = target.dataset.automationField
      let auto = foundry.utils.duplicate(this.document.system.automations)
      auto[index][field] = target.value
      auto[index].id = auto[index].id || foundry.utils.randomID(16)
      this.document.update({ 'system.automations': auto })
      return
    }

    super._onChangeForm(formConfig, event)
  }
}
