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

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


    // Ailments
    const ailmentField = (label) => {
      const schema = {
        enabled: new fields.BooleanField({ required: true, initial: false }),
        label: new fields.StringField({ required: true, initial: label })
      }
      return new fields.SchemaField(schema, { label })
    }
    schema.ailments = new fields.SchemaField(
      Object.values(SYSTEM.AILMENTS).reduce((obj, ailment) => {
        obj[ailment.id] = ailmentField(ailment.label)
        return obj
      }, {}),
    )

    // Stats
    const statField = (label) => {
      const schema = {
        label: new fields.StringField({ required: true, initial: label }),
        value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),

      }
      return new fields.SchemaField(schema, { label })
    }
    schema.stats = new fields.SchemaField(
      Object.values(SYSTEM.STATS).reduce((obj, stat) => {
        obj[stat.id] = statField(stat.label)
        return obj
      }, {}),
    )

    schema.backstory = new fields.HTMLField({ required: true, textSearch: true })
    schema.appearance = new fields.HTMLField({ required: true, textSearch: true })
    schema.scars = new fields.HTMLField({ required: true, textSearch: true })
    schema.likes  = new fields.HTMLField({ required: true, textSearch: true })
    schema.dislikes = new fields.HTMLField({ required: true, textSearch: true })
    schema.fears = new fields.HTMLField({ required: true, textSearch: true })
    schema.vices = new fields.HTMLField({ required: true, textSearch: true })
    schema.goals = new fields.HTMLField({ required: true, textSearch: true })
    schema.ambitions = new fields.HTMLField({ required: true, textSearch: true })
    schema.values = new fields.HTMLField({ required: true, textSearch: true })
    schema.bonds  = new fields.HTMLField({ required: true, textSearch: true })
    schema.notes = new fields.HTMLField({ required: true, textSearch: true })

    schema.pronouns = new fields.StringField({ required: true, nullable: false, initial: "" })
    schema.species = new fields.StringField({ required: true, nullable: false, initial: "" })
    schema.trait = new fields.StringField({ required: true, nullable: false, initial: "" })

    schema.limboes = new fields.StringField({ required: true, nullable: false, initial: "" })
    schema.ammo = new fields.StringField({ required: true, nullable: false, initial: "" })

    const ammoField = (label) => {
      const schema = {
        label: new fields.StringField({ required: true, initial: label }),
        value: new fields.StringField({ required: true, initial: "" }),
      }
      return new fields.SchemaField(schema, { label })
    }
    schema.ammoArray = new fields.SchemaField(
      Object.values(SYSTEM.AMMO_TYPES).reduce((obj, ammo) => {
        obj[ammo.id] = ammoField(ammo.label)
        return obj
      }, {}),
    )

    schema.mortality = new fields.SchemaField({
      /* Enabled: Array of 5 boolean field */
      enabled:  new fields.ArrayField(new fields.BooleanField(),
              { required: true, initial: [false, false, false, false, false], min:5, max:5 }),

      current: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
      max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
    })

    schema.trauma = new fields.SchemaField({
      current: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }),
      max: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }),
    })

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

    schema.defense = new fields.SchemaField({
      base: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
      bonus: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
      total: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
      resistance: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
    })

    schema.movement = new fields.SchemaField({
      base: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
      reduce: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
    })

    schema.experience = new fields.SchemaField({
      training: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
      current: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
      total: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
    })

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

    return schema
  }

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

  prepareDerivedData() {
    super.prepareDerivedData();

  }

  /** */
  /**
   * 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 HellbornRoll.prompt({
      rollType,
      rollItem,
      actorId: this.parent.id,
      actorName: this.parent.name,
      actorImage: this.parent.img,
      hasTarget,
      target: opponentTarget
    })
    if (!roll) return null

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