/**
 * DataModel pour les acteurs de type "npc" (PNJ).
 * Étend foundry.abstract.TypeDataModel.
 *
 * Conforme aux règles des PNJ (regles/regles_pnj.txt) : un PNJ n'a ni
 * caractéristiques chiffrées, ni réserves détaillées, ni liste de compétences.
 * Il est défini uniquement par son Profil (identité) et trois critères :
 * Menace, Expérience et Rôle. Toutes les valeurs utiles en jeu sont dérivées
 * des tableaux de référence (CONFIG.VERMINE.npc*Levels) et exposées dans
 * "system.computed".
 *
 * Note : le champ libre de description des Spécialités est nommé "freeSkills"
 * pour éviter le conflit avec le champ "skills" que le template.json historique
 * définissait comme texte libre pour les PNJ.
 */
import {
  woundSchema,
  combatStatusSchema,
  equipmentSchema,
  attributeSchema
} 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 utilise "freeSkills" pour cette description.
   * @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é (Profil du PNJ)
      identity: new fields.SchemaField({
        name: new fields.StringField({ required: true, nullable: false, initial: "" }),
        age: 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: "" })
      }),

      // Critères de définition du PNJ (Menace, Expérience, Rôle)
      threat: attributeSchema(1, 1, 4),
      experience: attributeSchema(1, 1, 4),
      role: attributeSchema(1, 1, 4),

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

      // Valeurs calculées (dérivées des niveaux de menace / expérience / rôle)
      computed: new fields.SchemaField({
        attack: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
        vigor: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
        action: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 3 }),
        specialties: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 4 }),
        rerolls: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
        contact: new fields.StringField({ required: true, nullable: false, initial: "7" }),
        reaction: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 3 }),
        reactionBonus: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
        pools: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
        gear: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 9 }),
        gearHindrance: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
        protection: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 1 })
      }),

      // Équipement
      equipment: equipmentSchema()
    }
  }

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

    // 1. Calculer les valeurs dérivées selon les niveaux de menace/expérience/rôle
    this._setNpcComputedValues()

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

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

  /**
   * Calcule les valeurs dérivées à partir des niveaux de Menace, Expérience
   * et Rôle. Utilise CONFIG.VERMINE.npcThreatLevels, .npcExperienceLevels
   * et .npcRoleLevels.
   */
  _setNpcComputedValues() {
    const threatLevel = this.threat?.value || 1
    const expLevel = this.experience?.value || 1
    const roleLevel = this.role?.value || 1

    const threatConfig = CONFIG.VERMINE.npcThreatLevels[threatLevel] || {}
    const expConfig = CONFIG.VERMINE.npcExperienceLevels[expLevel] || {}
    const roleConfig = CONFIG.VERMINE.npcRoleLevels[roleLevel] || {}

    // Menace
    this.computed.attack = threatConfig.attack || 0
    this.computed.vigor = threatConfig.vigor || 0

    // Expérience
    this.computed.action = expConfig.action || 3
    this.computed.specialties = expConfig.specialties || 4
    this.computed.rerolls = expConfig.rerolls || 0
    this.computed.contact = expConfig.contact || "7"

    // Rôle
    this.computed.reaction = roleConfig.reaction || 0
    this.computed.reactionBonus = roleConfig.reaction_bonus || 0
    this.computed.pools = roleConfig.pools || 0
    this.computed.gear = roleConfig.gear || 9
    this.computed.gearHindrance = roleConfig.gear_hindrance || 0
    this.computed.protection = roleConfig.protection || 1
  }

  /**
   * Calcule les seuils et le nombre de boîtes de blessures à partir du
   * niveau de menace (tableau "Niveau de Menace"). Utilise
   * CONFIG.VERMINE.npcThreatLevels.
   */
  _setNpcWoundThresholds() {
    const threatLevel = this.threat?.value || 1
    const threatConfig = CONFIG.VERMINE.npcThreatLevels[threatLevel] || {}

    this.minorWound.threshold = threatConfig.minorThreshold ?? 1
    this.majorWound.threshold = threatConfig.majorThreshold ?? 4
    this.deadlyWound.threshold = threatConfig.deadlyThreshold ?? 6

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

  /**
   * 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
    }
  }
}
