const { HandlebarsApplicationMixin } = foundry.applications.api

export default class CelestopolActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
  static SHEET_MODES = { EDIT: 0, PLAY: 1 }

  constructor(options = {}) {
    super(options)
    this.#dragDrop = this.#createDragDropHandlers()
  }

  #dragDrop

  /** @override */
  static DEFAULT_OPTIONS = {
    classes: ["fvtt-celestopol", "actor"],
    position: { width: 900, height: "auto" },
    form: { submitOnChange: true },
    window: { resizable: true },
    dragDrop: [{ dragSelector: '[data-drag="true"], .rollable', dropSelector: null }],
    actions: {
      editImage:    CelestopolActorSheet.#onEditImage,
      toggleSheet:  CelestopolActorSheet.#onToggleSheet,
      edit:         CelestopolActorSheet.#onItemEdit,
      delete:       CelestopolActorSheet.#onItemDelete,
    },
  }

  _sheetMode = this.constructor.SHEET_MODES.PLAY

  get isPlayMode() { return this._sheetMode === this.constructor.SHEET_MODES.PLAY }
  get isEditMode() { return this._sheetMode === this.constructor.SHEET_MODES.EDIT }

  /** @override */
  async _prepareContext() {
    return {
      fields:       this.document.schema.fields,
      systemFields: this.document.system.schema.fields,
      actor:        this.document,
      system:       this.document.system,
      source:       this.document.toObject(),
      isEditMode:   this.isEditMode,
      isPlayMode:   this.isPlayMode,
      isEditable:   this.isEditable,
    }
  }

  /** @override */
  _onRender(context, options) {
    this.#dragDrop.forEach(d => d.bind(this.element))
    this.element.querySelectorAll(".rollable").forEach(el => {
      el.addEventListener("click", this._onRoll.bind(this))
    })
    
    // Setup sequential checkbox logic for wound tracks
    this._setupSequentialCheckboxes()
    
    // Setup sequential checkbox logic for factions
    this._setupFactionCheckboxes()
  }

  /** @override */
  _onClick(event) {
    // Skip checkbox clicks in edit mode
    if (this.isEditMode && event.target.classList.contains('skill-level-checkbox')) {
      return
    }
    super._onClick(event)
  }

  async _onRoll(event) {
    // Don't roll if clicking on a checkbox
    if (event.target.classList.contains('skill-level-checkbox')) {
      return
    }
    if (!this.isPlayMode) return
    const el = event.currentTarget
    const statId  = el.dataset.statId
    const skillId = el.dataset.skillId
    if (!statId || !skillId) return
    await this.document.system.roll(statId, skillId)
  }

  #createDragDropHandlers() {
    return this.options.dragDrop.map(d => {
      d.permissions = {
        dragstart: this._canDragStart.bind(this),
        drop:      this._canDragDrop.bind(this),
      }
      d.callbacks = {
        dragover: this._onDragOver.bind(this),
        drop:     this._onDrop.bind(this),
      }
      return new foundry.applications.ux.DragDrop.implementation(d)
    })
  }

  _canDragStart()  { return this.isEditable }
  _canDragDrop()   { return true }
  _onDragOver()    {}

  async _onDrop(event) {
    if (!this.isEditable) return
    const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event)
    if (data.type === "Item") {
      const item = await fromUuid(data.uuid)
      if (item) return this._onDropItem(item)
    }
  }

  async _onDropItem(item) {
    if (item.type === "anomaly" && this.document.itemTypes.anomaly.length > 0) {
      ui.notifications.warn(game.i18n.localize("CELESTOPOL.Anomaly.maxAnomaly"))
      return
    }
    await this.document.createEmbeddedDocuments("Item", [item.toObject()], { renderSheet: false })
  }

  static async #onEditImage(event, _target) {
    const current = this.document.img
    const fp = new FilePicker({
      current,
      type: "image",
      callback: (path) => this.document.update({ img: path }),
      top:  this.position.top + 40,
      left: this.position.left + 10,
    })
    return fp.browse()
  }

  static #onToggleSheet() {
    const modes = this.constructor.SHEET_MODES
    this._sheetMode = this.isEditMode ? modes.PLAY : modes.EDIT
    this.render()
  }

  static async #onItemEdit(event, target) {
    const uuid = target.getAttribute("data-item-uuid")
    const id   = target.getAttribute("data-item-id")
    const item = uuid ? await fromUuid(uuid) : this.document.items.get(id)
    item?.sheet.render(true)
  }

  static async #onItemDelete(event, target) {
    const uuid = target.getAttribute("data-item-uuid")
    const item = await fromUuid(uuid)
    await item?.deleteDialog()
  }

  /**
   * Setup sequential checkbox logic for wound/destin/spleen tracks
   * Only allows checking the next checkbox in sequence
   */
  _setupSequentialCheckboxes() {
    this.element.querySelectorAll('.wound-checkbox').forEach(checkbox => {
      checkbox.addEventListener('change', (event) => {
        this._handleSequentialCheckboxChange(event)
      })
    })
  }

  /**
   * Handle sequential checkbox change logic
   * @param {Event} event - The change event
   */
  _handleSequentialCheckboxChange(event) {
    const checkbox = event.target
    if (!checkbox.classList.contains('wound-checkbox') || checkbox.disabled) return
    
    const track = checkbox.dataset.track
    const currentIndex = parseInt(checkbox.dataset.index)
    const isChecked = checkbox.checked
    
    // Get all checkboxes in this track
    const trackCheckboxes = Array.from(this.element.querySelectorAll(`.wound-checkbox[data-track="${track}"]`))
    
    if (isChecked) {
      // Checking a box: uncheck all boxes after this one
      for (let i = currentIndex + 1; i < trackCheckboxes.length; i++) {
        trackCheckboxes[i].checked = false
      }
      // Check all boxes before this one
      for (let i = 0; i < currentIndex; i++) {
        trackCheckboxes[i].checked = true
      }
    } else {
      // Unchecking a box: uncheck all boxes after this one
      for (let i = currentIndex; i < trackCheckboxes.length; i++) {
        trackCheckboxes[i].checked = false
      }
    }
    
    // Update the visual state
    this._updateTrackVisualState()
  }

  /**
   * Update visual state of track boxes based on checkbox states
   */
  _updateTrackVisualState() {
    this.element.querySelectorAll('.track-box').forEach(box => {
      const checkbox = box.querySelector('.wound-checkbox')
      if (checkbox) {
        if (checkbox.checked) {
          box.classList.add('checked')
        } else {
          box.classList.remove('checked')
        }
      }
    })
  }

  /**
   * Setup sequential checkbox logic for faction tracks
   */
  _setupFactionCheckboxes() {
    this.element.querySelectorAll('.faction-checkbox').forEach(checkbox => {
      checkbox.addEventListener('change', (event) => {
        this._handleFactionCheckboxChange(event)
      })
    })
  }

  /**
   * Handle faction checkbox change logic
   * @param {Event} event - The change event
   */
  _handleFactionCheckboxChange(event) {
    const checkbox = event.target
    if (!checkbox.classList.contains('faction-checkbox') || checkbox.disabled) return
    
    const factionId = checkbox.dataset.faction
    const currentLevel = parseInt(checkbox.dataset.level)
    const isChecked = checkbox.checked
    
    // Get all checkboxes for this faction
    const factionCheckboxes = Array.from(this.element.querySelectorAll(`.faction-checkbox[data-faction="${factionId}"]`))
    
    if (isChecked) {
      // Checking a box: check all boxes before this one, uncheck all boxes after this one
      for (let i = 0; i < currentLevel; i++) {
        factionCheckboxes[i].checked = true
      }
      for (let i = currentLevel; i < factionCheckboxes.length; i++) {
        factionCheckboxes[i].checked = false
      }
    } else {
      // Unchecking a box: uncheck all boxes after this one
      for (let i = currentLevel - 1; i < factionCheckboxes.length; i++) {
        factionCheckboxes[i].checked = false
      }
    }
    
    // Update the count display
    this._updateFactionCount(factionId)
  }

  /**
   * Update the faction count display based on checked checkboxes
   * @param {string} factionId - The faction ID
   */
  _updateFactionCount(factionId) {
    const checkboxes = Array.from(this.element.querySelectorAll(`.faction-checkbox[data-faction="${factionId}"]:checked`))
    const count = checkboxes.length
    
    // Update the hidden input field
    const input = this.element.querySelector(`input[name="system.factions.${factionId}.value"]`)
    if (input) {
      input.value = count
    }
    
    // Update the visual count display
    const countDisplay = this.element.querySelector(`.faction-row[data-faction="${factionId}"] .faction-count`)
    if (countDisplay) {
      countDisplay.textContent = count
    }
  }
}
