import OathHammerActorSheet from "./base-actor-sheet.mjs"

const ALLOWED_LOOT_TYPES = new Set(["weapon", "armor", "ammunition", "equipment", "magic-item"])

export default class OathHammerPartySheet extends OathHammerActorSheet {
  /** @override */
  static DEFAULT_OPTIONS = {
    classes: ["party"],
    position: { width: 780, height: 600 },
    window: { contentClasses: ["party-content"] },
    actions: {
      openMember:     OathHammerPartySheet.#onOpenMember,
      removeMember:       OathHammerPartySheet.#onRemoveMember,
      moveMemberUp:       OathHammerPartySheet.#onMoveMemberUp,
      moveMemberDown:     OathHammerPartySheet.#onMoveMemberDown,
      toggleCarriesLight: OathHammerPartySheet.#onToggleCarriesLight,
      adjustCurrency: OathHammerPartySheet.#onAdjustCurrency,
      adjustQty:      OathHammerPartySheet.#onAdjustQty,
    },
  }

  /** @override */
  static PARTS = {
    main:    { template: "systems/fvtt-oath-hammer/templates/actor/party-sheet.hbs" },
    tabs:    { template: "templates/generic/tab-navigation.hbs" },
    members: { template: "systems/fvtt-oath-hammer/templates/actor/party-members.hbs" },
    loot:    { template: "systems/fvtt-oath-hammer/templates/actor/party-loot.hbs" },
    notes:   { template: "systems/fvtt-oath-hammer/templates/actor/party-notes.hbs" },
  }

  tabGroups = { sheet: "members" }

  #getTabs() {
    const tabs = {
      members: { id: "members", group: "sheet", icon: "fa-solid fa-users",         label: "OATHHAMMER.Tab.Members" },
      loot:    { id: "loot",    group: "sheet", icon: "fa-solid fa-treasure-chest", label: "OATHHAMMER.Tab.Loot" },
      notes:   { id: "notes",  group: "sheet", icon: "fa-solid fa-book",           label: "OATHHAMMER.Tab.Notes" },
    }
    for (const v of Object.values(tabs)) {
      v.active   = this.tabGroups[v.group] === v.id
      v.cssClass = v.active ? "active" : ""
    }
    return tabs
  }

  /** @override */
  async _prepareContext() {
    const context = await super._prepareContext()
    context.tabs = this.#getTabs()
    return context
  }

  /** @override */
  async _preparePartContext(partId, context) {
    const doc = this.document
    switch (partId) {
      case "main": {
        const lootItems = doc.items.contents.filter(i => ALLOWED_LOOT_TYPES.has(i.type))
        context.currentSlots = lootItems.reduce((sum, i) => {
          const slots = i.system.slots ?? 0
          const qty   = i.system.quantity ?? 1
          return sum + slots * qty
        }, 0)
        break
      }

      case "members": {
        context.tab = context.tabs.members
        const refs = doc.system.memberRefs ?? []
        context.members = refs.map((ref, idx) => {
          const actor = game.actors?.get(ref.id)
          if (!actor) return null
          const sys = actor.system
          const isNpc = actor.type === "npc"
          const classItem = !isNpc ? actor.items?.find(i => i.type === "class") : null
          return {
            id:           actor.id,
            name:         actor.name,
            img:          actor.img,
            type:         actor.type,
            idx,
            position:     idx + 1,
            isFirst:      idx === 0,
            isLast:       idx === refs.length - 1,
            carriesLight: ref.carriesLight ?? false,
            classLabel:   isNpc
              ? game.i18n.localize(`OATHHAMMER.NpcSubtype.${sys.subtype === "creature" ? "Creature" : "Npc"}`)
              : (classItem?.name ?? "—"),
            lineage:      !isNpc ? (sys.lineage?.name || "—") : "—",
            current:      !isNpc ? (sys.experience?.current ?? "—") : "—",
            grit:         sys.grit ? `${sys.grit.value}/${sys.grit.max}` : "—",
          }
        }).filter(Boolean)
        break
      }

      case "loot": {
        context.tab = context.tabs.loot
        const allItems = doc.items.contents.filter(i => ALLOWED_LOOT_TYPES.has(i.type))
        context.lootItems = allItems.map(i => ({
          id: i.id, uuid: i.uuid, img: i.img, name: i.name,
          type: i.type,
          typeLabel: game.i18n.localize(`TYPES.Item.${i.type}`),
          system: i.system,
        }))
        break
      }

      case "notes":
        context.tab = context.tabs.notes
        context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
          doc.system.notes ?? "", { async: true }
        )
        break
    }
    return context
  }

  /** @override */
  async _onDrop(event) {
    if (!this.isEditable || !this.isEditMode) return
    const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event)

    if (data.type === "Actor") {
      const actor = await fromUuid(data.uuid)
      if (!actor || !["character", "npc"].includes(actor.type)) return
      const refs = foundry.utils.deepClone(this.document.system.memberRefs ?? [])
      if (refs.some(r => r.id === actor.id)) return
      refs.push({ id: actor.id, carriesLight: false })
      return this.document.update({ "system.memberRefs": refs })
    }

    if (data.type === "Item") {
      const item = await fromUuid(data.uuid)
      if (!item || !ALLOWED_LOOT_TYPES.has(item.type)) return
      return this._onDropItem(item)
    }
  }

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

  static async #onOpenMember(event, target) {
    const actor = game.actors?.get(target.dataset.actorId)
    if (actor) actor.sheet.render(true)
  }

  static async #onRemoveMember(event, target) {
    const id   = target.dataset.actorId
    const refs = (this.document.system.memberRefs ?? []).filter(r => r.id !== id)
    await this.document.update({ "system.memberRefs": refs })
  }

  static async #onMoveMemberUp(event, target) {
    const idx  = parseInt(target.dataset.idx, 10)
    if (idx <= 0) return
    const refs = foundry.utils.deepClone(this.document.system.memberRefs ?? []);
    [refs[idx - 1], refs[idx]] = [refs[idx], refs[idx - 1]]
    await this.document.update({ "system.memberRefs": refs })
  }

  static async #onMoveMemberDown(event, target) {
    const idx  = parseInt(target.dataset.idx, 10)
    const refs = foundry.utils.deepClone(this.document.system.memberRefs ?? [])
    if (idx >= refs.length - 1) return;
    [refs[idx], refs[idx + 1]] = [refs[idx + 1], refs[idx]]
    await this.document.update({ "system.memberRefs": refs })
  }

  static async #onToggleCarriesLight(event, target) {
    const idx  = parseInt(target.dataset.idx, 10)
    const refs = foundry.utils.deepClone(this.document.system.memberRefs ?? [])
    if (!refs[idx]) return
    refs[idx].carriesLight = !refs[idx].carriesLight
    await this.document.update({ "system.memberRefs": refs })
  }

  static async #onAdjustCurrency(event, target) {
    const field  = target.dataset.field
    const delta  = parseInt(target.dataset.delta, 10)
    const cur    = foundry.utils.getProperty(this.document, field) ?? 0
    await this.document.update({ [field]: Math.max(0, cur + delta) })
  }

  static async #onAdjustQty(event, target) {
    const item  = this.document.items.get(target.dataset.itemId)
    const delta = parseInt(target.dataset.delta, 10)
    if (!item) return
    const qty = (item.system.quantity ?? 1) + delta
    if (qty <= 0) return item.delete()
    await item.update({ "system.quantity": qty })
  }
}
