
import { SYSTEM } from "./config/system.mjs"

export default class FTLNomadUtils {

  static registerSettings() {
    game.settings.register("fvtt-ftl-nomad", "settings-era", {
      name: game.i18n.localize("FTLNOMAD.Settings.era"),
      hint: game.i18n.localize("FTLNOMAD.Settings.eraHint"),
      default: "jazz",
      scope: "world",
      type: String,
      choices: SYSTEM.AVAILABLE_SETTINGS,
      config: true,
      onChange: _ => window.location.reload()
    });
  }

  static async loadCompendiumData(compendium) {
    const pack = game.packs.get(compendium)
    return await pack?.getDocuments() ?? []
  }

  static async loadCompendium(compendium, filter = item => true) {
    let compendiumData = await FTLNomadUtils.loadCompendiumData(compendium)
    return compendiumData.filter(filter)
  }

  static registerHandlebarsHelpers() {

    Handlebars.registerHelper('isNull', function (val) {
      return val == null;
    });

    Handlebars.registerHelper('exists', function (val) {
      return val != null && val !== undefined;
    });

    Handlebars.registerHelper('isEmpty', function (list) {
      if (list) return list.length === 0;
      else return false;
    });

    Handlebars.registerHelper('notEmpty', function (list) {
      return list.length > 0;
    });

    Handlebars.registerHelper('isNegativeOrNull', function (val) {
      return val <= 0;
    });

    Handlebars.registerHelper('isNegative', function (val) {
      return val < 0;
    });

    Handlebars.registerHelper('isPositive', function (val) {
      return val > 0;
    });

    Handlebars.registerHelper('equals', function (val1, val2) {
      return val1 === val2;
    });

    Handlebars.registerHelper('neq', function (val1, val2) {
      return val1 !== val2;
    });

    Handlebars.registerHelper('gt', function (val1, val2) {
      return val1 > val2;
    })

    Handlebars.registerHelper('lt', function (val1, val2) {
      return val1 < val2;
    })

    Handlebars.registerHelper('gte', function (val1, val2) {
      return val1 >= val2;
    })

    Handlebars.registerHelper('lte', function (val1, val2) {
      return val1 <= val2;
    })
    Handlebars.registerHelper('and', function (val1, val2) {
      return val1 && val2;
    })
    Handlebars.registerHelper('or', function (val1, val2) {
      return val1 || val2;
    })

    Handlebars.registerHelper('or3', function (val1, val2, val3) {
      return val1 || val2 || val3;
    })

    Handlebars.registerHelper('for', function (from, to, incr, block) {
      let accum = '';
      for (let i = from; i < to; i += incr)
        accum += block.fn(i);
      return accum;
    })

    Handlebars.registerHelper('not', function (cond) {
      return !cond;
    })
    Handlebars.registerHelper('count', function (list) {
      return list.length;
    })
    Handlebars.registerHelper('countKeys', function (obj) {
      return Object.keys(obj).length;
    })

    Handlebars.registerHelper('isEnabled', function (configKey) {
      return game.settings.get("bol", configKey);
    })
    Handlebars.registerHelper('split', function (str, separator, keep) {
      return str.split(separator)[keep];
    })

    // If you need to add Handlebars helpers, here are a few useful examples:
    Handlebars.registerHelper('concat', function () {
      let outStr = '';
      for (let arg in arguments) {
        if (typeof arguments[arg] != 'object') {
          outStr += arguments[arg];
        }
      }
      return outStr;
    })

    Handlebars.registerHelper('add', function (a, b) {
      return parseInt(a) + parseInt(b);
    });
    Handlebars.registerHelper('mul', function (a, b) {
      return parseInt(a) * parseInt(b);
    })
    Handlebars.registerHelper('sub', function (a, b) {
      return parseInt(a) - parseInt(b);
    })
    Handlebars.registerHelper('abbrev2', function (a) {
      return a.substring(0, 2);
    })
    Handlebars.registerHelper('abbrev3', function (a) {
      return a.substring(0, 3);
    })
    Handlebars.registerHelper('valueAtIndex', function (arr, idx) {
      return arr[idx];
    })
    Handlebars.registerHelper('includesKey', function (items, type, key) {
      return items.filter(i => i.type === type).map(i => i.system.key).includes(key);
    })
    Handlebars.registerHelper('includes', function (array, val) {
      return array.includes(val);
    })
    Handlebars.registerHelper('eval', function (expr) {
      return eval(expr);
    })
    Handlebars.registerHelper('isOwnerOrGM', function (actor) {
      console.log("Testing actor", actor.isOwner, game.userId)
      return actor.isOwner || game.isGM;
    })
    Handlebars.registerHelper('upperFirst', function (text) {
      if (typeof text !== 'string') return text
      return text.charAt(0).toUpperCase() + text.slice(1)
    })
    Handlebars.registerHelper('upperFirstOnly', function (text) {
      if (typeof text !== 'string') return text
      return text.charAt(0).toUpperCase()
    })
    Handlebars.registerHelper('isCreature', function (key) {
      return key === "creature" || key === "daemon";
    })

    // Handle v12 removal of this helper
    Handlebars.registerHelper('select', function (selected, options) {
      const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected));
      const rgx = new RegExp(' value=[\"\']' + escapedValue + '[\"\']');
      const html = options.fn(this);
      return html.replace(rgx, "$& selected");
    });

  }

  static setupCSSRootVariables() {
    const era = game.settings.get("fvtt-cthulhu-eternal", "settings-era")

    let eraCSS = SYSTEM.ERA_CSS[era];
    if (!eraCSS) eraCSS = SYSTEM.ERA_CSS["jazz"];

    document.documentElement.style.setProperty('--font-size-standard', eraCSS.baseFontSize);
    document.documentElement.style.setProperty('--font-size-title', eraCSS.titleFontSize);
    document.documentElement.style.setProperty('--font-size-result', eraCSS.titleFontSize);
    document.documentElement.style.setProperty('--font-primary', eraCSS.primaryFont);
    document.documentElement.style.setProperty('--font-secondary', eraCSS.secondaryFont);
    document.documentElement.style.setProperty('--font-title', eraCSS.titleFont);
    document.documentElement.style.setProperty('--img-icon-color-filter', eraCSS.imgFilter);
    document.documentElement.style.setProperty('--background-image-base', `linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), url("../assets/ui/${era}_background_main.webp")`);
  }

  static getTechAgeKeyFromLabel(label) {
    return Object.keys(SYSTEM.TECH_AGES).find(key => game.i18n.localize(SYSTEM.TECH_AGES[key].label) === label);
  }

  static async importPsionics() {
    // Create a psionics folder if it doesn't exist
    const psionicsFolder = game.folders.getName("Psionics") || await Folder.create({
      name: "Psionics", type: "Item"
    })
    if (!psionicsFolder) {
      console.error("Failed to create Psionics folder");
      return;
    }
    // Load the psionics JSON file
    const psionicsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/psionics.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load psionics data:", error);
        return [];
      });
    // Import each psionic ability
    for (const psionic of psionicsData) {
      // Check if the psionic already exists
      const existingPsionic = game.items.find(i => i.name === psionic.name && i.type === "psionic");
      if (existingPsionic) {
        console.warn(`Psionic ${psionic.name} already exists, skipping import.`);
        continue;
      }
      // Create the psionic item
      await Item.create({
        name: psionic.name,
        type: "psionic",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_psionic.svg",
        system: {
          description: psionic.description,
        },
        folder: psionicsFolder.id
      });
    }
  }

  static async importTalents() {
    // Create a talents folder if it doesn't exist
    const talentsFolder = game.folders.getName("Talents") || await Folder.create({
      name: "Talents", type: "Item"
    })
    if (!talentsFolder) {
      console.error("Failed to create Talents folder");
      return;
    }
    // Load the talents JSON file
    const talentsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/talents.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load talents data:", error);
        return [];
      });
    // Import each talent
    for (const talent of talentsData) {
      // Check if the talent already exists
      const existingTalent = game.items.find(i => i.name === talent.name && i.type === "talent");
      if (existingTalent) {
        console.warn(`Talent ${talent.name} already exists, skipping import.`);
        continue;
      }
      talent.advantage = false;
      if (talent.description.includes(" +1D")) {
        talent.advantage = true
      }
      // Create the talent item
      await Item.create({
        name: talent.name,
        type: "talent",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_talent.svg",
        system: {
          description: talent.description,
          isAdvantage: talent.advantage,
        },
        folder: talentsFolder.id
      });
    }
  }

  static async importImplants() {
    // Create a implants folder if it doesn't exist
    const implantsFolder = game.folders.getName("Implants") || await Folder.create({
      name: "Implants", type: "Item"
    })
    if (!implantsFolder) {
      console.error("Failed to create Implants folder");
      return;
    }
    // Load the implants JSON file
    const implantsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/implants.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load implants data:", error);
        return [];
      });
    // Import each implant
    for (const implant of implantsData) {
      // Check if the implant already exists
      const existingImplant = game.items.find(i => i.name === implant.name && i.type === "implant");
      if (existingImplant) {
        console.warn(`Implant ${implant.name} already exists, skipping import.`);
        continue;
      }
      if (!Number(implant.cost)) {
        implant.cost = 1000000;
      }
      // Create the implant item
      await Item.create({
        name: implant.name,
        type: "implant",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_implant.svg",
        system: {
          cost: implant.cost,
          loss: implant.loss,
          techAge: this.getTechAgeKeyFromLabel(implant.tech_age),
          description: implant.description,
        },
        folder: implantsFolder.id
      });
    }
  }

  static async importDrugs() {
    // Create a drugs folder if it doesn't exist
    const drugsFolder = game.folders.getName("Drugs") || await Folder.create({
      name: "Drugs", type: "Item"
    })
    if (!drugsFolder) {
      console.error("Failed to create Drugs folder");
      return;
    }
    // Load the drugs JSON file
    const drugsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/drugs.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load drugs data:", error);
        return [];
      });
    // Import each drug
    for (const drug of drugsData) {
      // Check if the drug already exists
      const existingDrug = game.items.find(i => i.name === drug.name && i.type === "drug");
      if (existingDrug) {
        console.warn(`Drug ${drug.name} already exists, skipping import.`);
        continue;
      }
      // Create the drug item
      await Item.create({
        name: drug.name,
        type: "equipment",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_equipment.svg",
        system: {
          description: drug.description,
          cost: drug.cost,
          techAge: this.getTechAgeKeyFromLabel(drug.tech_age),
        },
        folder: drugsFolder.id
      });
    }
  }

  static async importEquipments() {
    // Create a equipments folder if it doesn't exist
    const equipmentsFolder = game.folders.getName("Equipments") || await Folder.create({
      name: "Equipments", type: "Item"
    })
    if (!equipmentsFolder) {
      console.error("Failed to create Equipments folder");
      return;
    }
    // Load the equipments JSON file
    const equipmentsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/exploration_equipment.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load equipments data:", error);
        return [];
      });
    // Import each equipment
    for (const equipment of equipmentsData) {
      // Check if the equipment already exists
      const existingEquipment = game.items.find(i => i.name === equipment.name && i.type === "equipment");
      if (existingEquipment) {
        console.warn(`Equipment ${equipment.name} already exists, skipping import.`);
        continue;
      }
      if (!Number(equipment.cost)) {
        equipment.cost = 1000000;
      }

      // Create the equipment item
      await Item.create({
        name: equipment.name,
        type: "equipment",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_equipment.svg",
        system: {
          description: equipment.description,
          cost: equipment.cost,
          techAge: this.getTechAgeKeyFromLabel(equipment.tech_age),
        },
        folder: equipmentsFolder.id
      });
    }
  }

  static async importDistanceWeapons() {
    // Create a distance weapons folder if it doesn't exist
    const distanceWeaponsFolder = game.folders.getName("Vehicle Weapons") || await Folder.create({
      name: "Vehicle Weapons", type: "Item"
    })
    if (!distanceWeaponsFolder) {
      console.error("Failed to create Distance Weapons folder");
      return;
    }
    // Load the distance weapons JSON file
    const distanceWeaponsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/vehicle_weapons.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load distance weapons data:", error);
        return [];
      });

    // Import each distance weapon
    for (const weapon of distanceWeaponsData) {
      // Check if the weapon already exists
      const existingWeapon = game.items.find(i => i.name === weapon.name && i.type === "weapon");
      if (existingWeapon) {
        console.warn(`Weapon ${weapon.name} already exists, skipping import.`);
        continue;
      }
      // Create the weapon item
      await Item.create({
        name: weapon.name,
        type: "weapon",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_weapon.svg",
        system: {
          description: weapon.description,
          damage: weapon.damage,
          techAge: this.getTechAgeKeyFromLabel(weapon.tech_age),
          weaponType: SYSTEM.WEAPON_TYPES.vehicle.id,
          rangeType: weapon.range.toLowerCase(),
          enc: 0,
          aspect: weapon.aspects.join(", "),
          cost: weapon.cost || 0,
          ammoCost: weapon.ammo_cost || 0,
          magazine: weapon.mag || 1,
        },
        folder: distanceWeaponsFolder.id
      });
    }
  }

  static async importStarships() {
    // Create a starships folder if it doesn't exist
    const starshipsFolder = game.folders.getName("Starships") || await Folder.create({
      name: "Starships", type: "Actor"
    })
    if (!starshipsFolder) {
      console.error("Failed to create Starships folder");
      return;
    }
    // Load the starships JSON file
    const starshipsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/starships.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load starships data:", error);
        return [];
      });

    // Import each starship
    for (const starship of starshipsData) {
      // Check if the starship already exists
      const existingStarship = game.actors.find(a => a.name === starship.name && a.type === "starship");
      if (existingStarship) {
        console.warn(`Starship ${starship.name} already exists, skipping import.`);
        continue;
      }
      // Create the starship actor
      await Actor.create({
        name: starship.name,
        type: "starship",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_starship.svg",
        system: {
          description: starship.description,
          agility: starship.agility,
          hullType: starship.hullType.toLowerCase(),
          endurance: starship.endurance,
          armor: starship.armor,
          crew: starship.crew,
          cargo: starship.cargo,
          guns: starship.guns,
          travelMultiplier: starship.travelMultiplier,
          cost: starship.cost || 0,
          monthlyCost: starship.monthlyCost || 0,
          damages: starship.damages,
        },
        folder: starshipsFolder.id
      });
    }
  }

  static async importVehicles() {
    // Create a vehicles folder if it doesn't exist
    const vehiclesFolder = game.folders.getName("Vehicles") || await Folder.create({
      name: "Vehicles", type: "Actor"
    })
    if (!vehiclesFolder) {
      console.error("Failed to create Vehicles folder");
      return;
    }
    // Load the vehicles JSON file
    const vehiclesData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/vehicles.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load vehicles data:", error);
        return [];
      });

    // Import each vehicle
    for (const vehicle of vehiclesData) {
      // Check if the vehicle already exists
      const existingVehicle = game.items.find(i => i.name === vehicle.name && i.type === "vehicle");
      if (existingVehicle) {
        console.warn(`Vehicle ${vehicle.name} already exists, skipping import.`);
        continue;
      }
      // Create the vehicle item
      await Actor.create({
        name: vehicle.name,
        type: "vehicle",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_vehicle.svg",
        system: {
          description: vehicle.description,
          agility: vehicle.agility,
          armor: vehicle.armor,
          cargo: vehicle.cargo,
          crew: vehicle.crew,
          force: vehicle.force,
          range: vehicle.range,
          speed: vehicle.speed,
          techAge: this.getTechAgeKeyFromLabel(vehicle.tech_age),
          tonnage: vehicle.tonnage,
          damages: vehicle.damages,
          cost: vehicle.cost || 0,
        },
        folder: vehiclesFolder.id
      });
    }
  }

  static async importArmors() {
    // Create an armors folder if it doesn't exist
    const armorsFolder = game.folders.getName("Armors") || await Folder.create({
      name: "Armors", type: "Item"
    })
    if (!armorsFolder) {
      console.error("Failed to create Armors folder");
      return;
    }
    // Load the armors JSON file
    const armorsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/armors.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load armors data:", error);
        return [];
      });

    // Import each armor
    for (const armor of armorsData) {
      // Check if the armor already exists
      const existingArmor = game.items.find(i => i.name === armor.name && i.type === "armor");
      if (existingArmor) {
        console.warn(`Armor ${armor.name} already exists, skipping import.`);
        continue;
      }
      // Create the armor item
      await Item.create({
        name: armor.name,
        type: "armor",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_armor.svg",
        system: {
          description: armor.description,
          enc: armor.enc || 0,
          techAge: this.getTechAgeKeyFromLabel(armor.tech_age),
          cost: armor.cost || 0,
          protection: armor.protection || 0,
        },
        folder: armorsFolder.id
      });
    }
  }

  static async importGrenadeWeapons() {
    // Create a grenade weapons folder if it doesn't exist
    const grenadeWeaponsFolder = game.folders.getName("Grenade") || await Folder.create({
      name: "Grenade", type: "Item"
    })
    if (!grenadeWeaponsFolder) {
      console.error("Failed to create Grenade Weapons folder");
      return;
    }
    // Load the grenade weapons JSON file
    const grenadeWeaponsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/grenades.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load grenade weapons data:", error);
        return [];
      });

    // Import each grenade weapon
    for (const weapon of grenadeWeaponsData) {
      // Check if the weapon already exists
      const existingWeapon = game.items.find(i => i.name === weapon.name && i.type === "weapon");
      if (existingWeapon) {
        console.warn(`Weapon ${weapon.name} already exists, skipping import.`);
        continue;
      }
      // Create the weapon item
      await Item.create({
        name: weapon.name,
        type: "weapon",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_weapon.svg",
        system: {
          description: weapon.description,
          damage: weapon.damage,
          techAge: this.getTechAgeKeyFromLabel(weapon.tech_age),
          weaponType: SYSTEM.WEAPON_TYPES.grenade.id,
          rangeType: SYSTEM.WEAPON_RANGE.thrownweapon.id,
          enc: 0,
          aspect: weapon.aspects.join(", "),
          cost: weapon.cost || 0,
          ammoCost: 0,
        },
        folder: grenadeWeaponsFolder.id
      });
    }
  }

  static async fixWeaponsEnc() {
    // Iterate over all items of type "weapon" from compendium
    const weapons = game.items.filter(i => i.type === "weapon");
    for (const weapon of weapons) {
      // If the weapon's encumbrance is less than 1, set it to 1
      if (weapon.system.enc < 1) {
        await weapon.update({ "system.enc": 1 });
      }
    }
  }

  static async fixEquipmentEnc() {
    // Iterate over all items of type "equipment" from compendium
    const equipments = game.items.filter(i => i.type === "equipment");
    for (const equipment of equipments) {
      // If the equipment's encumbrance is less than 1, set it to
      if (equipment.system.enc < 1) {
        await equipment.update({ "system.enc": 1 });
      }
    }
  }

  static async importMeleeWeapons() {
    // Create a melee weapons folder if it doesn't exist
    const meleeWeaponsFolder = game.folders.getName("Melee Weapons") || await Folder.create({
      name: "Melee Weapons", type: "Item"
    })
    if (!meleeWeaponsFolder) {
      console.error("Failed to create Melee Weapons folder");
      return;
    }
    // Load the melee weapons JSON file
    const meleeWeaponsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/weapon_melee.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load melee weapons data:", error);
        return [];
      });

    console.log("Melee Weapons Data", meleeWeaponsData);
    // Import each melee weapon
    for (const weapon of meleeWeaponsData) {
      // Check if the weapon already exists
      const existingWeapon = game.items.find(i => i.name === weapon.name && i.type === "weapon");
      if (existingWeapon) {
        console.warn(`Weapon ${weapon.name} already exists, skipping import.`);
        continue;
      }
      // Create the weapon item
      await Item.create({
        name: weapon.name,
        type: "weapon",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_weapon.svg",
        system: {
          description: weapon.description,
          damage: weapon.damage,
          techAge: this.getTechAgeKeyFromLabel(weapon.tech_age),
          weaponType: SYSTEM.WEAPON_TYPES.melee.id,
          rangeType: SYSTEM.WEAPON_RANGE.melee.id,
          enc: 0,
          aspect: weapon.aspects.join(", "),
          cost: weapon.cost || 0,
          ammoCost: 0,
        },
        folder: meleeWeaponsFolder.id
      });
    }
  }

  static async importVehicleWeapons() {
    // Create a melee weapons folder if it doesn't exist
    const meleeWeaponsFolder = game.folders.getName("Vehicle Weapons") || await Folder.create({
      name: "Vehicle Weapons", type: "Item"
    })
    if (!meleeWeaponsFolder) {
      console.error("Failed to create Vehicle Weapons folder");
      return;
    }
    // Load the melee weapons JSON file
    const meleeWeaponsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/vehicleweapons.json")
      .then(response => response.json())
      .catch(error => {
        console.error("Failed to load vehicle weapons data:", error);
        return [];
      });

    console.log("vehicle Weapons Data", meleeWeaponsData);
    // Import each melee weapon
    for (const weapon of meleeWeaponsData) {
      // Check if the weapon already exists
      const existingWeapon = game.items.find(i => i.name === weapon.name && i.type === "weapon");
      if (existingWeapon) {
        console.warn(`Weapon ${weapon.name} already exists, skipping import.`);
      }
      // Create the weapon item
      await Item.create({
        name: weapon.name,
        type: "weapon",
        img: "systems/fvtt-ftl-nomad/assets/icons/icon_weapon.svg",
        system: {
          description: weapon.description,
          damage: weapon.damage,
          techAge: this.getTechAgeKeyFromLabel(weapon.tech_age),
          weaponType: "vehicle", //SYSTEM.WEAPON_TYPES.melee.id,
          rangeType: SYSTEM.WEAPON_RANGE.melee.id,
          enc: 0,
          aspect: weapon.aspects,
          cost: weapon.cost || 0,
          ammoCost: weapon.ammo_cost || 0,
          magazine: weapon.mag || 1,
        },
        folder: meleeWeaponsFolder.id
      });
    }
  }

}
