const { HandlebarsApplicationMixin } = foundry.applications.api

/**
 * Fiche de base pour tous les items Vermine 2047 (ApplicationV2).
 */
export class VermineBaseItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {

  // ── Mode édition ────────────────────────────────────────────────────

  static SHEET_MODES = { EDIT: 0, PLAY: 1 }

  _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 }

  // ── Options par défaut ──────────────────────────────────────────────

  static DEFAULT_OPTIONS = {
    classes: ["vermine2047", "item"],
    position: { width: 560, height: "auto" },
    form: { submitOnChange: true },
    window: { resizable: true },
    actions: {
      editImage: VermineBaseItemSheet.#onEditImage,
      toggleSheet: VermineBaseItemSheet.#onToggleSheet,
      clickDamage: VermineBaseItemSheet.#onClickDamage,
      openTraits: VermineBaseItemSheet.#onOpenTraits,
      reliabilityTest: VermineBaseItemSheet.#onReliabilityTest,
      reliabilityRepair: VermineBaseItemSheet.#onReliabilityRepair
    }
  }

  // ── Drag & Drop ─────────────────────────────────────────────────────

  #dragDrop

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

  #createDragDropHandlers() {
    if (!this.options.dragDrop) return []
    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 this.isEditable }

  // ── Contexte commun ─────────────────────────────────────────────────

  async _prepareContext() {
    return {
      fields: this.document.schema.fields,
      systemFields: this.document.system.schema.fields,
      item: this.document,
      system: this.document.system,
      source: this.document.toObject(),
      config: CONFIG.VERMINE,
      enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }),
      isEditMode: this.isEditMode,
      isPlayMode: this.isPlayMode,
      isEditable: this.isEditable
    }
  }

  // ── Rendu ───────────────────────────────────────────────────────────

  _onRender(context, options) {
    super._onRender(context, options);
    this.#dragDrop.forEach(d => d.bind(this.element))
  }

  // ── Sauvegarde ───────────────────────────────────────────────────────

  /** @override */
  _prepareSubmitData(event, form, formData, updateData) {
    return super._prepareSubmitData(event, form, formData, updateData)
  }

  // ── Actions ─────────────────────────────────────────────────────────

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

  static async #onEditImage(event, target) {
    const attr = target.dataset.edit ?? "img"
    const current = foundry.utils.getProperty(this.document, attr)
    const fp = new FilePicker({
      current,
      type: "image",
      callback: (path) => this.document.update({ [attr]: path }),
      top: this.position.top + 40,
      left: this.position.left + 10
    })
    return fp.browse()
  }

  static #onClickDamage(event, target) {
    // Les radios de dégâts sont 1-based dans le template (value="{{@index}}" avec index 1..max)
    // mais le stockage est 0-based. On soustrait 1 avant de sauvegarder.
    const prop = target.name
    const value = parseInt(target.value) - 1
    this.document.update({ [prop]: value })
  }

  static async #onOpenTraits(event, target) {
    const { TraitSelector } = await import("../../system/applications.mjs")
    new TraitSelector(this.document).render(true)
  }

  static async #onReliabilityTest() {
    const { default: ReliabilityDialog } = await import("../../system/dialogs/reliabilityDialog.mjs")
    const dialog = await ReliabilityDialog.create({ item: this.document, mode: "test" })
    await dialog.render(true)
  }

  static async #onReliabilityRepair() {
    const { default: ReliabilityDialog } = await import("../../system/dialogs/reliabilityDialog.mjs")
    const dialog = await ReliabilityDialog.create({ item: this.document, mode: "repair" })
    await dialog.render(true)
  }
}
