/**
 * Schémas partagés pour les DataModels Vermine 2047.
 * Fonctions factory retournant des objets SchemaField réutilisables.
 */

const fields = foundry.data.fields

/** NumberField qui accepte les strings vides en les remplaçant par `initial`. */
class LooseNumberField extends fields.NumberField {
  clean(value, options) {
    if (value === "" || value === null || value === undefined) {
      return this.initial ?? 0
    }
    return super.clean(value, options)
  }
}

/**
 * Retourne un schema pour une blessure (minor/major/deadly)
 * @param {number} defaultThreshold
 * @param {number} defaultMax
 * @returns {Object}
 */
export function woundSchema(defaultThreshold = 1, defaultMax = 5) {
  const fields = foundry.data.fields
  const reqInt = { required: true, nullable: false, integer: true }
  return {
    threshold: new fields.NumberField({ ...reqInt, initial: defaultThreshold, min: 0 }),
    value: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }),
    min: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }),
    max: new fields.NumberField({ ...reqInt, initial: defaultMax, min: 0 })
  }
}

/**
 * Schema des 3 types de blessures présents sur tous les acteurs.
 */
export function woundsSchema() {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    minorWound: new fields.SchemaField(woundSchema(1, 5)),
    majorWound: new fields.SchemaField(woundSchema(4, 4)),
    deadlyWound: new fields.SchemaField(woundSchema(8, 2))
  })
}

/**
 * Statut de combat (offensif/actif/passif).
 */
export function combatStatusSchema(defaultDifficulty = "7") {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    label: new fields.StringField({ required: true, nullable: false, initial: "" }),
    difficulty: new fields.StringField({ required: true, nullable: false, initial: defaultDifficulty })
  })
}

/**
 * Description d'équipement.
 */
export function equipmentSchema() {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    description: new fields.HTMLField({ required: true, initial: "", textSearch: true })
  })
}

/**
 * Attribut avec value/min/max.
 * @param {number} defaultVal
 * @param {number} defaultMin
 * @param {number} defaultMax
 */
export function attributeSchema(defaultVal = 0, defaultMin = 0, defaultMax = 10) {
  const fields = foundry.data.fields
  const reqInt = { required: true, nullable: false, integer: true }
  return new fields.SchemaField({
    value: new LooseNumberField({ ...reqInt, initial: defaultVal, min: defaultMin }),
    min: new fields.NumberField({ ...reqInt, initial: defaultMin, min: 0 }),
    max: new fields.NumberField({ ...reqInt, initial: defaultMax, min: 0 })
  })
}

/**
 * Caractéristique (capacité) avec catégorie.
 * @param {string} category - physical, manual, mental, social
 */
export function abilityField(category) {
  const fields = foundry.data.fields
  const reqInt = { required: true, nullable: false, integer: true }
  return new fields.SchemaField({
    value: new fields.NumberField({ ...reqInt, initial: 1, min: 0, max: 5 }),
    min: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }),
    max: new fields.NumberField({ ...reqInt, initial: 5, min: 0 }),
    category: new fields.StringField({ required: true, nullable: false, initial: category })
  })
}

/**
 * Les 8 caractéristiques communes à character et npc.
 */
export function abilitiesSchema() {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    vigor: abilityField("physical"),
    health: abilityField("physical"),
    precision: abilityField("manual"),
    reflexes: abilityField("manual"),
    knowledge: abilityField("mental"),
    perception: abilityField("mental"),
    will: abilityField("social"),
    empathy: abilityField("social")
  })
}

/**
 * Une compétence individuelle.
 * @param {string} category
 * @param {number} rarity - 0, 1, ou 2
 */
export function skillField(category, rarity = 0) {
  const fields = foundry.data.fields
  const reqInt = { required: true, nullable: false, integer: true }
  return new fields.SchemaField({
    value: new fields.NumberField({ ...reqInt, initial: 0, min: 0, max: 5 }),
    min: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }),
    max: new fields.NumberField({ ...reqInt, initial: 5, min: 0 }),
    category: new fields.StringField({ required: true, nullable: false, initial: category }),
    rarity: new fields.NumberField({ ...reqInt, initial: rarity, min: 0, max: 2 })
  })
}

/**
 * Les 30 compétences (character et npc).
 */
export function skillsSchema() {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    // man
    arts: skillField("man", 1),
    civilization: skillField("man", 2),
    psychology: skillField("man", 1),
    rumors: skillField("man", 0),
    healing: skillField("man", 1),
    // animal
    animalism: skillField("animal", 1),
    dissection: skillField("animal", 2),
    wildlife: skillField("animal", 1),
    repulsion: skillField("animal", 0),
    tracks: skillField("animal", 0),
    // tool
    crafting: skillField("tool", 2),
    diy: skillField("tool", 0),
    mecanical: skillField("tool", 2),
    piloting: skillField("tool", 1),
    technology: skillField("tool", 2),
    // weapon
    firearms: skillField("weapon", 2),
    archery: skillField("weapon", 0),
    armory: skillField("weapon", 2),
    throwing: skillField("weapon", 0),
    melee: skillField("weapon", 0),
    // survival
    alertness: skillField("survival", 0),
    atletics: skillField("survival", 0),
    food: skillField("survival", 0),
    stealth: skillField("survival", 0),
    close: skillField("survival", 0),
    // world
    environment: skillField("world", 1),
    flora: skillField("world", 1),
    road: skillField("world", 0),
    toxics: skillField("world", 2),
    ruins: skillField("world", 1)
  })
}

/**
 * Catégories de compétences avec domaine de prédilection.
 */
export function skillCategoriesSchema() {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    preferred: new fields.StringField({ required: true, nullable: false, initial: "" }),
    man: new fields.SchemaField({
      label: new fields.StringField({ required: true, initial: "VERMINE.skill_category.man" }),
      preferred: new fields.BooleanField({ required: true, initial: false })
    }),
    animal: new fields.SchemaField({
      label: new fields.StringField({ required: true, initial: "VERMINE.skill_category.animal" }),
      preferred: new fields.BooleanField({ required: true, initial: false })
    }),
    tool: new fields.SchemaField({
      label: new fields.StringField({ required: true, initial: "VERMINE.skill_category.tool" }),
      preferred: new fields.BooleanField({ required: true, initial: false })
    }),
    weapon: new fields.SchemaField({
      label: new fields.StringField({ required: true, initial: "VERMINE.skill_category.weapon" }),
      preferred: new fields.BooleanField({ required: true, initial: false })
    }),
    survival: new fields.SchemaField({
      label: new fields.StringField({ required: true, initial: "VERMINE.skill_category.survival" }),
      preferred: new fields.BooleanField({ required: true, initial: false })
    }),
    world: new fields.SchemaField({
      label: new fields.StringField({ required: true, initial: "VERMINE.skill_category.world" }),
      preferred: new fields.BooleanField({ required: true, initial: false })
    })
  })
}

// ── Item shared schemas ──────────────────────────────────────────────────

const reqInt = { required: true, nullable: false, integer: true }

/**
 * Rareté avec handicap.
 */
export function raritySchema() {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    value: new fields.NumberField({ ...reqInt, initial: 3, min: 1, max: 10 }),
    handicap: new fields.NumberField({ ...reqInt, initial: 0, min: 0 })
  })
}

/**
 * Dégâts des items (hors arme).
 */
export function itemDamagesSchema() {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    value: new fields.NumberField({ ...reqInt, initial: 0, min: 0, max: 5 }),
    min: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }),
    max: new fields.NumberField({ ...reqInt, initial: 5, min: 0 }),
    pannes: new fields.ArrayField(new fields.StringField({ required: true, initial: "" }), {
      initial: ["mineure", "mineure", "grave", "grave", "critique"]
    }),
    state: new fields.ArrayField(new fields.StringField({ required: true, initial: "" }), {
      initial: ["endommagé", "endommagé", "défectueux", "défectueux", "hors d'usage"]
    }),
    effect: new fields.ArrayField(new fields.StringField({ required: true, initial: "" }), {
      initial: ["bonus annulé", "bonus annulé", "malus 1D", "malus 1D", "inutilisable"]
    })
  })
}

/**
 * Base commune à tous les items (template "base" dans l'ancien template.json).
 */
export function baseItemSchema() {
  const fields = foundry.data.fields
  return {
    description: new fields.HTMLField({ required: true, initial: "", textSearch: true }),
    rarity: raritySchema(),
    reliability: new fields.NumberField({ ...reqInt, initial: 3, min: 0, max: 10 }),
    handicap: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }),
    quantity: new fields.NumberField({ ...reqInt, initial: 1, min: 1 }),
    weight: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }),
    traits: new fields.ObjectField({ required: true, initial: {} }),
    damages: itemDamagesSchema()
  }
}

/**
 * Template "list" pour les items abstraits (ability, background, trauma, evolution, rumor, target).
 * Version légère avec seulement description.
 */
export function listItemSchema() {
  const fields = foundry.data.fields
  return {
    description: new fields.HTMLField({ required: true, initial: "", textSearch: true })
  }
}

/**
 * Schéma d'apprentissage pour les abilities.
 */
export function learnSchema() {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    threshold: new fields.NumberField({ ...reqInt, initial: 5, min: 0 }),
    hindrance: new fields.NumberField({ ...reqInt, initial: 0, min: 0 })
  })
}

/**
 * Niveau générique (value/min/max).
 */
export function levelSchema(defaultVal = 1, defaultMin = 1, defaultMax = 5) {
  const fields = foundry.data.fields
  return new fields.SchemaField({
    value: new fields.NumberField({ ...reqInt, initial: defaultVal, min: defaultMin }),
    min: new fields.NumberField({ ...reqInt, initial: defaultMin, min: 0 }),
    max: new fields.NumberField({ ...reqInt, initial: defaultMax, min: 0 })
  })
}
