/**
 * DataModel pour les acteurs de type "npc" (PNJ).
 * Étend foundry.abstract.TypeDataModel.
 *
 * Note : le champ libre de compétences (texte descriptif) est nommé "freeSkills"
 * pour éviter le conflit avec le SchemaField "skills" qui contient les 30 compétences.
 */
import {
  woundSchema,
  combatStatusSchema,
  equipmentSchema,
  attributeSchema,
  abilitiesSchema,
  skillCategoriesSchema,
  skillsSchema
} from "./_shared.mjs"

export default class VermineNpcData extends foundry.abstract.TypeDataModel {

  /** @override */
  static LOCALIZATION_PREFIXES = ["VERMINE.npc"]

  /**
   * Migration des données avant traitement par le schéma.
   * Avant DataModel, template.json définissait "skills" comme un champ texte libre
   * pour les PNJ. Le DataModel réserve "skills" pour les 30 compétences individuelles
   * (SchemaField) et utilise "freeSkills" pour le texte libre.
   * @param {Object} source Données brutes avant validation du schéma
   * @returns {Object} Données migrées
   */
  static migrateData(source) {
    if (typeof source.skills === "string") {
      source.freeSkills = source.skills
    }
    return super.migrateData(source)
  }

  /** @override */
  static defineSchema() {
    const fields = foundry.data.fields

    return {
      // Blessures (base)
      minorWound: new fields.SchemaField(woundSchema(1, 5)),
      majorWound: new fields.SchemaField(woundSchema(4, 4)),
      deadlyWound: new fields.SchemaField(woundSchema(8, 2)),

      // Statut de combat (base, difficulté par défaut 9 pour PNJ)
      combatStatus: combatStatusSchema("9"),

      // Identité
      identity: new fields.SchemaField({
        name: new fields.StringField({ required: true, nullable: false, initial: "" }),
        profile: new fields.StringField({ required: true, nullable: false, initial: "" }),
        origin: new fields.StringField({ required: true, nullable: false, initial: "" }),
        totem: new fields.StringField({ required: true, nullable: false, initial: "" }),
        theme: new fields.StringField({ required: true, nullable: false, initial: "" }),
        notes: new fields.HTMLField({ required: true, initial: "" })
      }),

      // Attributs (XP, réputation, sang-froid, effort)
      attributes: new fields.SchemaField({
        xp: attributeSchema(0, 0, 10),
        reputation: attributeSchema(0, 0, 10),
        self_control: attributeSchema(0, 0, 5),
        effort: attributeSchema(0, 0, 5)
      }),

      // Niveaux PNJ (menace, expérience, rôle)
      threat: attributeSchema(1, 1, 4),
      experience: attributeSchema(1, 1, 4),
      role: attributeSchema(1, 1, 4),

      // Compétences (les 30 compétences individuelles)
      skills: skillsSchema(),

      // Description libre des compétences (champ texte PNJ)
      freeSkills: new fields.StringField({ required: true, nullable: false, initial: "" }),

      // Catégories de compétences
      skill_categories: skillCategoriesSchema(),

      // Caractéristiques (8)
      abilities: abilitiesSchema(),

      // Équipement
      equipment: equipmentSchema()
    }
  }

  /** @override */
  prepareDerivedData() {
    super.prepareDerivedData()

    // 1. Calculer les seuils de blessures selon le niveau de menace
    this._setNpcWoundThresholds()

    // 2. Calculer les réserves selon le niveau de rôle
    this._setNpcAttributes()

    // 3. Définir les libellés des caractéristiques
    this._setAbilityLabels()

    // 4. Mettre à jour le statut de combat
    this._updateCombatStatus()
  }

  /**
   * Calcule les seuils de blessures à partir du niveau de menace.
   * Utilise CONFIG.VERMINE.npcThreatLevels.
   */
  _setNpcWoundThresholds() {
    const health = this.abilities?.health?.value || 1
    const threatLevel = this.threat?.value || 1
    const threatConfig = CONFIG.VERMINE.npcThreatLevels[threatLevel] || {}

    this.minorWound.threshold = health
    this.majorWound.threshold = health + 3
    this.deadlyWound.threshold = Math.min(health + 7, 10)

    this.minorWound.max = threatConfig.minorWound || 1
    this.majorWound.max = threatConfig.majorWound || 1
    this.deadlyWound.max = threatConfig.deadlyWound || 1
  }

  /**
   * Définit les attributs dérivés (effort, sang-froid) selon le niveau de rôle.
   * Utilise CONFIG.VERMINE.npcRoleLevels.
   */
  _setNpcAttributes() {
    const roleLevel = this.role?.value || 1
    const roleConfig = CONFIG.VERMINE.npcRoleLevels[roleLevel] || {}

    this.attributes.effort.max = roleConfig.pools || 0
    this.attributes.self_control.max = roleConfig.reaction_bonus || 0
  }

  /**
   * Définit les libellés localisés des caractéristiques.
   */
  _setAbilityLabels() {
    for (const [k, v] of Object.entries(this.abilities)) {
      v.label = game.i18n.localize(CONFIG.VERMINE.abilities[k]) ?? k
    }
  }

  /**
   * Met à jour le label du statut de combat en fonction de la difficulté.
   */
  _updateCombatStatus() {
    const difficulty = parseInt(this.combatStatus.difficulty) || 9
    let newLabel = "Passif"
    switch (difficulty) {
      case 5: newLabel = "Offensif"; break
      case 7: newLabel = "Actif"; break
      case 9: newLabel = "Passif"; break
    }
    if (this.combatStatus.label !== newLabel) {
      this.combatStatus.label = newLabel
    }
  }
}
