import LesOubliesActorSheet from "./base-actor-sheet.mjs"
import { LesOubliesUtility } from "../../les-oublies-utility.js"

export default class LesOubliesPersonnageSheet extends LesOubliesActorSheet {
  static CREATION_DROP_TYPES = new Set(["race", "tribu", "metier"])

  static DEFAULT_OPTIONS = {
    ...super.DEFAULT_OPTIONS,
    classes: [...super.DEFAULT_OPTIONS.classes, "personnage"],
    actions: {
      ...super.DEFAULT_OPTIONS.actions,
      switchTab: LesOubliesPersonnageSheet.#onSwitchTab,
      removeCreationItem: LesOubliesPersonnageSheet.#onRemoveCreationItem,
    },
    window: {
      ...super.DEFAULT_OPTIONS.window,
      title: "TYPES.Actor.personnage",
    },
  }

  static PARTS = {
    sheet: {
      template: "systems/fvtt-les-oublies/templates/actor-personnage-sheet-v18.hbs",
    },
  }

  _activeTab = "overview"

  #getTabs() {
    const tabs = {
      overview: { id: "overview", label: "Portrait", icon: "fa-solid fa-id-card" },
      skills: { id: "skills", label: "Compétences", icon: "fa-solid fa-book-open" },
      actions: { id: "actions", label: "Combat & magie", icon: "fa-solid fa-wand-sparkles" },
      equipment: { id: "equipment", label: "Équipement", icon: "fa-solid fa-suitcase" },
      notes: { id: "notes", label: "Notes", icon: "fa-solid fa-feather-pointed" },
    }

    for (const tab of Object.values(tabs)) {
      tab.active = this._activeTab === tab.id
      tab.cssClass = tab.active ? "active" : ""
    }

    return tabs
  }

  async _prepareContext() {
    const context = await super._prepareContext()
    context.tabs = this.#getTabs()
    context.derived = this.document.getDerivedOverview()
    context.creation = {
      race: this.document.getCreationItem("race"),
      tribu: this.document.getCreationItem("tribu"),
      metier: this.document.getCreationItem("metier"),
    }
    context.creationSlots = [
      this.#buildCreationSlot("race", context.creation.race, "Glissez une race ici depuis un compendium ou le répertoire des objets."),
      this.#buildCreationSlot("tribu", context.creation.tribu, "Glissez une tribu ici depuis un compendium ou le répertoire des objets."),
      this.#buildCreationSlot("metier", context.creation.metier, "Glissez un métier ici depuis un compendium ou le répertoire des objets."),
    ]
    context.skillGroups = this.document.getGroupedCompetences()
    const splitIndex = Math.ceil(context.skillGroups.length / 2)
    context.skillColumns = [
      context.skillGroups.slice(0, splitIndex),
      context.skillGroups.slice(splitIndex),
    ]
    context.spells = this.document.getEmbeddedItems("sortilege")
    context.weapons = this._prepareWeaponEntries(this.document.getEmbeddedItems("arme"))
    context.equippedWeapons = context.weapons.filter((item) => item.system.equipped)
    context.armors = this.document.getEmbeddedItems("armure")
    context.equipment = this.document.getEmbeddedItems("equipement")
    context.companyPowers = this.document.getEmbeddedItems("pouvoircompagnie")
    context.activeCompanyPower = context.derived.compagnie?.getEmbeddedItems?.("pouvoircompagnie")?.[0] ?? null
    context.choiceSets.companyOptions = LesOubliesUtility.ensureChoice(
      LesOubliesUtility.sortByName(game.actors.filter((actor) => actor.type === "compagnie")).map((actor) => ({
        value: actor.id,
        label: actor.name,
      })),
      this.document.system.references?.compagnieId,
      context.derived.compagnie?.name,
    )
    return context
  }

  #buildCreationSlot(type, item, emptyHint) {
    return {
      type,
      label: game.i18n.localize(`TYPES.Item.${type}`),
      item,
      emptyHint,
      filledHint: "Déposez un autre élément du même type pour le remplacer.",
    }
  }

  async _onDrop(event) {
    const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event)
    if (data.type !== "Item" || !data.uuid) return super._onDrop(event)

    const item = await fromUuid(data.uuid)
    if (!item) return

    const slot = event.target?.closest?.("[data-drop-creation-type]")
    const slotType = slot?.dataset?.dropCreationType ?? ""
    const inCreationZone = Boolean(event.target?.closest?.("[data-creation-drop-zone]"))

    if (!LesOubliesPersonnageSheet.CREATION_DROP_TYPES.has(item.type)) {
      if (slot || inCreationZone) {
        ui.notifications.warn("Seules les races, tribus et métiers peuvent être déposés dans cette zone.")
        return
      }
      return super._onDrop(event)
    }

    if (slotType && slotType !== item.type) {
      ui.notifications.warn(`Déposez ici un élément de type ${game.i18n.localize(`TYPES.Item.${slotType}`)}.`)
      return
    }

    if (slot || inCreationZone) {
      await this.document.assignCreationItem(item)
      this.render()
      return
    }

    return super._onDrop(event)
  }

  static #onSwitchTab(event, target) {
    const tab = target.dataset.tab
    if (!tab || this._activeTab === tab) return
    this._activeTab = tab
    this.render()
  }

  static async #onRemoveCreationItem(event, target) {
    const type = target.dataset.type
    if (!LesOubliesPersonnageSheet.CREATION_DROP_TYPES.has(type)) return
    await this.document.clearCreationItem(type)
    this.render()
  }
}
