const __compFolderTranslation = [
  {
    compendium: 'swade-core-rules.swade-vehicles',
    words: [
      { source: 'Vehicles', translation: 'Véhicules' },
      { source: 'Aircraft', translation: 'Avions' },
      { source: 'Civilian', translation: 'Civils' },
      { source: 'Modern Military Aircraft', translation: 'Avions Militaires Modernes' },
      { source: 'World War II Military Aircraft', translation: 'Avions Seconde Guerre Mondiale' },
    ]
  }
]

class FolderTranslate {

  static async translateFolders() {

    for (let tData of __compFolderTranslation) {
      let pack = game.packs.get(tData.compendium);
      let wasLocked = false;
      if (pack.locked) {
        await pack.configure({ locked: false })
        wasLocked = true;
      }
      let folders = await game.CF.FICFolderAPI.loadFolders(tData.compendium);

      for (let trans of tData.words) {
        let folderToChange = folders.contents.find(f => f.name === trans.source);
        if (folderToChange) {
          await game.CF.FICFolderAPI.renameFolder(folderToChange, trans.translation);
        }
      }
      if (wasLocked) {
        await pack.configure({ locked: true })
      }
    }
  }
}

/************************************************************************************/
Hooks.once('translateCompendiumFolders', () => {
  console.log("LOADED !!!!!!")
});

/************************************************************************************/
class swadeFrTranslator {
  static getRank(rank) {
    if (rank == 'Novice') return 'Novice';
    if (rank == 'Seasoned') return 'Aguerri';
    if (rank == 'Veteran') return 'Vétéran';
    if (rank == 'Heroic') return 'Héroïque';
    if (rank == 'Legendary') return 'Légendaire';
    return false
  }
  static getAttribute(attr) {
    console.log("Attr is", attr)
    if (attr == "Agility") return 'Agilité';
    if (attr == "Smarts") return 'Intellect';
    if (attr == "Spirit") return 'Ame';
    if (attr == "Strength") return 'Force';
    if (attr == "Vigor") return 'Vigueur';
    return false
  }
}


/************************************************************************************/
Hooks.once('init', () => {

  if (typeof Babele !== 'undefined') {

    console.log("BABELE LOADED !!!");
    Babele.get().register({
      module: 'swade-fr-content',
      lang: 'fr',
      dir: 'compendiums'
    });

    Babele.get().registerConverters({
      "gear_skill": (skill) => {
        let transl = skill
        if (skill) {
          let translated = game.babele.translate("swade-core-rules.swade-skills", { name: skill.trim() }, true)
          transl = translated.name || skill.trim()
        }
        return transl
      },
      "edge_requirements": (req) => {
        let reqTab = req.split(",")
        let results = []
        for (let item of reqTab) {
          let keyName = item.match(/([\w\s\(\)]+) (d[\w\+]*)/)
          //console.log("Keyword", item, keyName)
          if (keyName && keyName[2]) { // This is a skill or attribute
            let toTranslate = keyName[1].trim()
            let attr = swadeFrTranslator.getAttribute(toTranslate)
            if (attr) { // Test if attribute
              results.push(attr + " " + keyName[2].trim())
            } else { // Test if skill
              let translated = game.babele.translate("swade-core-rules.swade-skills", { name: toTranslate }, true)
              if (!translated.name) {
                translated = game.babele.translate("deadlands-core-rules.deadlands-skills", { name: toTranslate }, true)
              }
              let transResult = translated.name || toTranslate
              results.push(transResult + " " + keyName[2].trim())
            }
          } else { // Rank or edge
            let itemName = item.trim()
            let rank = swadeFrTranslator.getRank(itemName)
            if (rank) {
              results.push(rank)
            } else {
              let translated = game.babele.translate("swade-core-rules.swade-edges", { name: itemName }, true)
              if (!translated.name) {
                translated = game.babele.translate("deadlands-core-rules.deadlands-edges", { name: itemName }, true)
              }
              let transResult = translated.name || itemName
              results.push(transResult)
            }
          }
        }
        console.log(">>>>>>>>>>>>>>>>>>>>>>>>><REQ !!!!", req, results)
        return results.join(", ")
      },
      "gear_range": (range) => {
        if (range) {
          if (range == 'Cone Template') return 'Gabarit de cone';
        }
        return range;
      },
      "gear_ammo": (ammo) => {
        if (ammo) {
          if (ammo == 'Arrows/Bolts') return 'Flèches/Carreaux';
          if (ammo == 'Canister Shot (Cannon)') return 'Cartouches (Canon)';
          if (ammo == 'Shrapnel Shot (Cannon)') return 'Shrapnel (Canon)';
          if (ammo == 'Solid Shot (Cannon)') return 'Solide (Canon)';
          if (ammo == 'Bullets, Medium') return 'Balles, Moyenne';
          if (ammo == 'Shotgun Shells') return 'Cartouche de Shotgun';
          if (ammo == 'Laser Battery, Pistol') return 'Batterie pour laser, Pistolet';
          if (ammo == 'Laser Battery, Rifle / SMG') return 'Batterie pour laser, Fusil';
        }
        return ammo;
      },
      "powers_duration": (duration) => {
        if (duration == 'One hour') return '1 heure';
        if (duration == 'Instant (slot); 5 (speed)') return 'Instantanée (apathie), 5 (vitesse)';
        if (duration == '(boost); Instant (lower)') return '5 (augmentation), Instantanée (diminution)';
        if (duration == 'Instant') return 'Instantannée';
        if (duration == 'Until the end of the victim\'s next turn') return 'Jusqu’à la fin du prochain tour de la victime';
        if (duration == 'A brief conversation of about five minutes') return 'Une brève conversation d\'environ 5 minutes';
        if (duration == '5 (detect), one hour (conceal)') return '5 (détection), 1 heure (dissimulation)';
        if (duration == 'Instant (Sound); 5 (Silence)') return 'Instantanée (son), 5 (silence)';
        return duration;
      },
      "powers_range": (range) => {
        if (range == 'Smarts x5 (Sound); Smarts (Silence)')
          return 'Intellect ×5 (son), Intellect (silence)';
        if (range == "Cone Template")
          return "Gabarit de cône"
        if (range == "Touch")
          return "Toucher"
        if (range == "Sm")
          return "Intellect"
        if (range == "Sm x 2" || range == "Sm x2")
          return "Intellect x2"
        if (range == "Self")
          return "Personnel"
        return range;
      },
      "powers_rank": (rank) => {
        return swadeFrTranslator.getRank(rank)
      }
    });
  }

});

/* -------------------------------------------- */
export class SwadeFRContentCommands {

  static init() {
    if (!game.swadeFRContent) {
      const swadeFRCommands = new SwadeFRContentCommands()
      swadeFRCommands.registerCommand({ path: ["/montremonsecret"], func: (content, msg, params) => SwadeFRContentCommands.enableSecret(), descr: "Affiche les compendiums secrets" });
      swadeFRCommands.registerCommand({ path: ["/cachemonsecret"], func: (content, msg, params) => SwadeFRContentCommands.disableSecret(), descr: "Cache les compendiums secrets" });
      game.swadeFRContent = { commands: swadeFRCommands }
    }

    Hooks.on("chatMessage", (html, content, msg) => {
      if (content[0] == '/') {
        let regExp = /(\S+)/g;
        let commands = content.match(regExp);
        if (game.swadeFRContent.commands.processChatCommand(commands, content, msg)) {
          return false;
        }
      }
      return true
    })

  }
  constructor() {
    this.commandsTable = {}
  }

  /* -------------------------------------------- */
  registerCommand(command) {
    this._addCommand(this.commandsTable, command.path, '', command);
  }

  /* -------------------------------------------- */
  _addCommand(targetTable, path, fullPath, command) {
    if (!this._validateCommand(targetTable, path, command)) {
      return;
    }
    const term = path[0];
    fullPath = fullPath + term + ' '
    if (path.length == 1) {
      command.descr = `<strong>${fullPath}</strong>: ${command.descr}`;
      targetTable[term] = command;
    }
    else {
      if (!targetTable[term]) {
        targetTable[term] = { subTable: {} };
      }
      this._addCommand(targetTable[term].subTable, path.slice(1), fullPath, command)
    }
  }

  /* -------------------------------------------- */
  _validateCommand(targetTable, path, command) {
    if (path.length > 0 && path[0] && command.descr && (path.length != 1 || targetTable[path[0]] == undefined)) {
      return true;
    }
    console.warn("Commande invalide", targetTable, path, command);
    return false;
  }


  /* -------------------------------------------- */
  /* Manage chat commands */
  processChatCommand(commandLine, content = '', msg = {}) {
    // Setup new message's visibility
    let rollMode = game.settings.get("core", "rollMode");
    if (["gmroll", "blindroll"].includes(rollMode)) msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
    if (rollMode === "blindroll") msg["blind"] = true;
    msg["type"] = 0;

    let command = commandLine[0].toLowerCase();
    let params = commandLine.slice(1);

    return this.process(command, params, content, msg);
  }

  /* -------------------------------------------- */
  process(command, params, content, msg) {
    return this._processCommand(this.commandsTable, command, params, content, msg);
  }

  /* -------------------------------------------- */
  static enableSecret() {
    game.settings.set("world", "swade-fr-content-hidden-compendiums", true)
  }
  /* -------------------------------------------- */
  static disableSecret() {
    game.settings.set("world", "swade-fr-content-hidden-compendiums", false)
  }

  /* -------------------------------------------- */
  _processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
    console.log("===> Processing command")
    let command = commandsTable[name];
    path = path + name + " ";
    if (command && command.subTable) {
      if (params[0]) {
        return this._processCommand(command.subTable, params[0], params.slice(1), content, msg, path)
      }
      else {
        this.help(msg, command.subTable);
        return true;
      }
    }
    if (command && command.func) {
      const result = command.func(content, msg, params);
      if (result == false) {
        BoLCommands._chatAnswer(msg, command.descr);
      }
      return true;
    }
    return false;
  }

}

/************************************************************************************/
const transFolder = { "Actor": "Acteur", "Edges": "Atouts" }
const subFolder = {
  'Social Edges': 'Atouts sociaux', 'Background Edges': 'Atouts de Background', 'Combat Edges': 'Atouts de combat',
  'Leadership Edges': 'Atouts de commandement', 'Legendary Edges': 'Atouts légendaires', 'Power Edges': 'Atouts de pouvoir',
  'Professional Edges': 'Atouts professionnels', 'Weird Edges': 'Atouts étranges', 'Edges': 'Atouts', 'Hindrances': 'Handicaps', 'Skills': 'Compétences',
  'Equipment': 'Equipement', 'Ammo': 'Munitions', 'Armor': 'Armure', 'Common Gear': 'Matériel commun', 'Modern Firearms': 'Armes à feu modernes',
  'Personal Weapons': 'Armes', 'Special Weapons': 'Armes spéciales', 'Bullet': 'Balles', 'Cannon': 'Canon', 'Laser Battery': 'Batterie Laser',
  'Adventuring Gear': 'Matériel d\'aventure', 'Animals and Tack': 'Animaux', 'Clothing': 'Vêtements', 'Computers & Electronics': 'Ordinateurs et Electroniques',
  'Firearms Accessories': 'Accessoires armes à feu', 'Food': 'Nourriture', 'Personal Defense': 'Auto-défense', 'Futuristic': 'Futuriste',
  'Medieval & Ancient': 'Médiévale et Antiquité', 'Modern': 'Moderne', 'Shields': 'Boucliers', 'Laser (Futuristic)': 'Laser (Fururiste)',
  'Machine Guns': 'Mitraillettes', 'Pistols': 'Pistolets', 'Rifles': 'Fusils', 'Submachine Guns': 'Semi-automatiques', 'Cannons': 'Canons',
  'Catapults': 'Catapultes', 'Flamethrowers': 'Lance-flammes', 'Rocket Launchers & Torpedoes': 'Lance roquettes et torpilles',
  'Vehicular Weapons': 'Armes de véhicules'
}

/************************************************************************************/
// Register world usage statistics
function registerUsageCount(registerKey) {
  if (game.user.isGM) {
    game.settings.register(registerKey, "world-key", {
      name: "Unique world key",
      scope: "world",
      config: false,
      default: "",
      type: String
    });

    let worldKey = game.settings.get(registerKey, "world-key")
    if (worldKey == undefined || worldKey == "") {
      worldKey = randomID(32)
      game.settings.set(registerKey, "world-key", worldKey)
    }
    // Simple API counter
    let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
    $.ajax(regURL)
    /* -------------------------------------------- */
  }
}

/************************************************************************************/
async function loadSecretCompendiums() {

  if (game.settings.get("world", "swade-fr-content-hidden-compendiums")) {
    console.log(">>>>> Load hidden compendiums!")
    /* Load rules */
    let urls = ["modules/swade-fr-content/compendiums/swade-core-rules.swade-rules-secret.json"]
    const [translations] = await Promise.all(
      [Promise.all(urls.map((url) => fetch(url).then((r) => r.json()).catch(e => { })))]);

    let metadata = game.data.packs.find(p => p.name == "swade-rules")
    if (metadata) {
      let translation;
      translations.forEach(t => {
        if (t) {
          translation = t; // the last valid
        }
      });
      if (translation) {
        let babele = Babele.get()
        let entry = mergeObject(translation, { collection: metadata.id })
        babele.translations.push(entry)
        console.log(">>>>", babele.translations)
        babele.packs.set(metadata.id, new TranslatedCompendium(metadata, entry))
      }
    }
  }
}

/************************************************************************************/
Hooks.once('ready', () => {

  // add hidden register
  game.settings.register("world", "swade-fr-content-hidden-compendiums", {
    name: "Montrer les compendiums cachés",
    scope: "world",
    config: false,
    default: false,
    type: Boolean,
    onChange: lang => window.location.reload()
  })

  SwadeFRContentCommands.init()

  //FolderTranslate.translateFolders()
  registerUsageCount("swade-fr-content")

});

/************************************************************************************/
Hooks.once('babele.ready', () => {
  loadSecretCompendiums()
});