import { SYSTEM } from "../config/system.mjs"
import FTLNomadRoll from "../documents/roll.mjs"

export default class FTLNomadProtagonist extends foundry.abstract.TypeDataModel {
  static defineSchema() {
    const fields = foundry.data.fields
    const requiredInteger = { required: true, nullable: false, integer: true }
    const schema = {}

    schema.description = new fields.HTMLField({ required: true, textSearch: true })
    schema.notes = new fields.HTMLField({ required: true, textSearch: true })
    schema.name = new fields.StringField({ required: true, nullable: false, initial: "" })
    schema.concept = new fields.StringField({ required: true, nullable: false, initial: "" })
    schema.species = new fields.StringField({ required: true, nullable: false, initial: "" })
    schema.archetype = new fields.StringField({ required: true, nullable: false, initial: "" })

    // Carac
    const skillField = (label) => {
      const schema = {
        value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 5 }),
        label: new fields.StringField({ required: true, nullable: false, initial: label })
      }
      return new fields.SchemaField(schema, { label })
    }

    schema.skills = new fields.SchemaField(
      Object.values(SYSTEM.SKILLS).reduce((obj, characteristic) => {
        obj[characteristic.id] = skillField(characteristic.label)
        return obj
      }, {}),
    )

    schema.heroPoints = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })

    schema.health = new fields.SchemaField({
      staminaValue: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }),
      staminaMax: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }),
      wounds: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
      triageResults: new fields.StringField({ required: true, nullable: false, initial: "none", choices: SYSTEM.TRIAGE_RESULTS })
    })

    schema.enc = new fields.SchemaField({
      value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
      max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
    })

    schema.armor = new fields.SchemaField({
      value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
    })

    schema.credits = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
    schema.rank = new fields.SchemaField({
      experienced: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 5 }),
      expert: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 5 }),
      veteran: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 5 }),
      elite: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 5 }),
      legend: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 5 })
    })

    schema.biodata = new fields.SchemaField({
      age: new fields.NumberField({ ...requiredInteger, initial: 15, min: 6 }),
      height: new fields.NumberField({ ...requiredInteger, initial: 170, min: 50 }),
      weight: new fields.NumberField({ ...requiredInteger, initial: 70, min: 1 }),
      gender: new fields.StringField({ required: true, nullable: false, initial: "" }),
      home: new fields.StringField({ required: true, nullable: false, initial: "" }),
      birthplace: new fields.StringField({ required: true, nullable: false, initial: "" }),
      eyes: new fields.StringField({ required: true, nullable: false, initial: "" }),
      hair: new fields.StringField({ required: true, nullable: false, initial: "" })
    })

    return schema
  }

  /** @override */
  static LOCALIZATION_PREFIXES = ["FTLNOMAD.Character"]

  prepareDerivedData() {
    super.prepareDerivedData();

    let encMax = this.enc.max // 10 + (2 * this.skills.physical.value)
    let enc = 0
    let armor = 0
    for (let i of this.parent.items) {
      if (i.system?.enc) {
        enc += i.system.enc
      }
      if (i.system?.protection) {
        armor += i.system.protection
      }
    }
    if (enc !== this.enc.value) {
      this.enc.value = enc
    }
    if (armor !== this.armor.value) {
      this.armor.value = armor
    }
    let staminaMax = 14 + (3 * this.skills.physical.value)
    if (staminaMax !== this.health.staminaMax) {
      this.health.staminaMax = staminaMax
    }
  }

  isEncumbered() {
    return this.enc.value > this.enc.max
  }

  /** */
  /**
   * Rolls a dice for a character.
   * @param {("save"|"resource|damage")} rollType The type of the roll.
   * @param {number} rollItem The target value for the roll. Which caracteristic or resource. If the roll is a damage roll, this is the id of the item.
   * @returns {Promise<null>} - A promise that resolves to null if the roll is cancelled.
   */
  async roll(rollType, rollItem) {
    let opponentTarget
    const hasTarget = opponentTarget !== undefined

    let roll = await FTLNomadRoll.prompt({
      rollType,
      rollItem,
      actorId: this.parent.id,
      actorName: this.parent.name,
      actorImage: this.parent.img,
      talents: this.parent.items.filter(i => i.type === "talent" && i.system.isAdvantage),
      isEncumbered: this.isEncumbered(),
      hasTarget,
      target: opponentTarget
    })
    if (!roll) return null

    await roll.toMessage({}, { rollMode: roll.options.rollMode })
  }
}
