const SKILL_LOCALIZATION_PREFIX = 'MGT2.Skills.';

export const COMMERCE_SKILLS = Object.freeze({
  passengerEffect: ['carouse', 'broker', 'streetwise'],
  cargoEffect: ['broker', 'streetwise'],
  tradeBroker: 'broker',
  steward: 'steward',
});

export function splitSkillFqn(skillFqn = '') {
  const [skillId = '', specialityId = ''] = String(skillFqn ?? '').split('.');
  return { skillId, specialityId };
}

export function localizeSkill(skillFqn, fallback = '') {
  const { skillId, specialityId } = splitSkillFqn(skillFqn);
  if (!skillId) return fallback;

  const skillLabel = localizeSkillId(skillId);
  if (!specialityId) return skillLabel;
  return `${skillLabel} (${localizeSkillId(specialityId)})`;
}

export function getActiveTravellerActor() {
  const controlled = canvas?.tokens?.controlled?.find((token) => token.actor?.type === 'traveller' || token.actor?.type === 'npc')?.actor;
  if (controlled) return { actor: controlled, source: 'token' };

  if (game.user?.character?.type === 'traveller' || game.user?.character?.type === 'npc') {
    return { actor: game.user.character, source: 'character' };
  }

  const owned = game.actors?.find((actor) => actor.isOwner && (actor.type === 'traveller' || actor.type === 'npc'));
  if (owned) return { actor: owned, source: 'owned' };

  return { actor: null, source: null };
}

export function getActorSkillSummary(actor, skillFqn) {
  if (!actor?.system?.skills) return buildEmptySkillSummary(skillFqn);

  const { skillId, specialityId } = splitSkillFqn(skillFqn);
  const skill = actor.system.skills[skillId];
  if (!skill) return buildEmptySkillSummary(skillFqn);

  const speciality = specialityId ? skill.specialities?.[specialityId] ?? null : null;
  const characteristic = speciality?.default || skill.default || null;
  const characteristicDm = characteristic ? Number(actor.system.characteristics?.[characteristic]?.dm ?? 0) : 0;
  const trained = Boolean(skill.trained) || Number(skill.value ?? 0) > 0 || Number(speciality?.value ?? 0) > 0;
  const value = speciality ? Number(speciality.value ?? 0) : Number(skill.value ?? 0);
  const jackOfAllTrades = Number(actor.system.skills?.jackofalltrades?.value ?? 0);
  const rollValue = trained ? value : jackOfAllTrades - 3;

  return {
    skillFqn,
    skillId,
    specialityId,
    label: localizeSkill(skillFqn, skill.label || skillId),
    value,
    rollValue,
    trained,
    characteristic,
    characteristicDm,
    totalModifier: rollValue + characteristicDm,
  };
}

export function getActorCharacteristicSummary(actor, characteristicId) {
  if (!actor?.system?.characteristics?.[characteristicId]) {
    return { id: characteristicId, value: 0, dm: 0, label: characteristicId };
  }

  const characteristic = actor.system.characteristics[characteristicId];
  return {
    id: characteristicId,
    value: Number(characteristic.value ?? 0),
    dm: Number(characteristic.dm ?? 0),
    label: game.i18n.localize(`MGT2.Characteristics.${characteristicId}`),
  };
}

export function getBestActorSkillSummary(actor, skillList = []) {
  const summaries = skillList
    .map((skillFqn) => getActorSkillSummary(actor, skillFqn))
    .filter((summary) => summary.skillId);

  if (!summaries.length) return null;

  return summaries.sort((left, right) => {
    if (right.totalModifier !== left.totalModifier) return right.totalModifier - left.totalModifier;
    if (right.value !== left.value) return right.value - left.value;
    return left.label.localeCompare(right.label, 'fr');
  })[0];
}

export async function rollActorSkillEffect(actor, skillList = [], difficulty = 8) {
  const summary = getBestActorSkillSummary(actor, skillList);
  if (!summary) return null;

  const roll = await new Roll('2d6').evaluate();
  const total = Number(roll.total ?? 0) + summary.totalModifier;
  return {
    ...summary,
    diceTotal: Number(roll.total ?? 0),
    total,
    effect: total - difficulty,
    difficulty,
  };
}

export function setSkillLevel(skills, skillFqn, level) {
  const { skillId, specialityId } = splitSkillFqn(skillFqn);
  if (!skillId || !skills?.[skillId]) return skills;

  const numericLevel = Number(level ?? 0);
  let skill = foundry.utils.deepClone(skills[skillId]);

  // Marquer la compétence comme entraînée si niveau > 0
  skill.trained = numericLevel > 0 || skill.trained;

  if (specialityId) {
    // Créer l'objet specialities s'il n'existe pas
    if (!skill.specialities) {
      skill.specialities = {};
    }
    // Créer la spécialité si elle n'existe pas
    if (!skill.specialities[specialityId]) {
      skill.specialities[specialityId] = {
        value: 0,
        trained: false,
        default: skill.default || null
      };
    }
    // Appliquer le niveau à la spécialité
    skill.specialities[specialityId] = foundry.utils.mergeObject(
      skill.specialities[specialityId],
      {
        value: Math.max(Number(skill.specialities[specialityId].value ?? 0), numericLevel),
        trained: true
      }
    );
  } else {
    // Compétence sans spécialité
    skill.value = Math.max(Number(skill.value ?? 0), numericLevel);
  }

  skills[skillId] = skill;
  return skills;
}

export function buildActiveActorContext() {
  const { actor, source } = getActiveTravellerActor();
  if (!actor) return null;

  return {
    id: actor.id,
    name: actor.name,
    source,
    sourceLabel: source === 'token' ? 'token sélectionné' : source === 'character' ? 'personnage assigné' : 'acteur possédé',
    broker: getActorSkillSummary(actor, 'broker'),
    carouse: getActorSkillSummary(actor, 'carouse'),
    streetwise: getActorSkillSummary(actor, 'streetwise'),
    steward: getActorSkillSummary(actor, 'steward'),
    soc: getActorCharacteristicSummary(actor, 'SOC'),
  };
}

export function inferWeaponSkillFromName(name, melee) {
  const label = String(name ?? '').toLowerCase();
  if (melee) {
    if (/(sabre|épée|epee|lame|poignard|couteau|fleuret|rapiere|rapière)/i.test(label)) return 'melee.blade';
    if (/(massue|matraque|bâton|baton|gourdin|marteau|masse)/i.test(label)) return 'melee.bludgeon';
    if (/(griffe|morsure|corne|tentacule|naturel)/i.test(label)) return 'melee.natural';
    return 'melee.unarmed';
  }

  if (/(laser|plasma|fusion|particule|meson)/i.test(label)) return 'guncombat.energy';
  if (/(arc|arbal[eè]te|javelot|lance[- ]?harpon)/i.test(label)) return 'guncombat.archaic';
  if (/(canon|lance[- ]?grenade|missile|mortier|roquette)/i.test(label)) return 'heavyweapons.portable';
  return 'guncombat.slug';
}

function localizeSkillId(skillId) {
  const localized = game.i18n.localize(`${SKILL_LOCALIZATION_PREFIX}${skillId}`);
  return localized.startsWith(SKILL_LOCALIZATION_PREFIX) ? skillId : localized;
}

function buildEmptySkillSummary(skillFqn) {
  const { skillId, specialityId } = splitSkillFqn(skillFqn);
  return {
    skillFqn,
    skillId,
    specialityId,
    label: localizeSkill(skillFqn, skillId),
    value: 0,
    rollValue: -3,
    trained: false,
    characteristic: null,
    characteristicDm: 0,
    totalModifier: -3,
  };
}
