export type SchwartzValue =
  | "selfDirection"
  | "stimulation"
  | "hedonism"
  | "achievement"
  | "power"
  | "security"
  | "conformity"
  | "tradition"
  | "benevolence"
  | "universalism";

export type SchwartzHigherOrder =
  | "opennessToChange"
  | "conservation"
  | "selfEnhancement"
  | "selfTranscendence";

const valueItems: Record<SchwartzValue, number[]> = {
  selfDirection: [1, 11, 21],
  stimulation: [2, 12, 22],
  hedonism: [3, 13, 23],
  achievement: [4, 14, 24],
  power: [5, 15, 25],
  security: [6, 16, 26],
  conformity: [7, 17, 27],
  tradition: [8, 18, 28],
  benevolence: [9, 19, 29],
  universalism: [10, 20, 30],
};

export const valueNames: Record<SchwartzValue, string> = {
  selfDirection: "自主",
  stimulation: "刺激",
  hedonism: "享乐",
  achievement: "成就",
  power: "权力",
  security: "安全",
  conformity: "遵从",
  tradition: "传统",
  benevolence: "仁慈",
  universalism: "普世主义",
};

export const higherOrderNames: Record<SchwartzHigherOrder, string> = {
  opennessToChange: "开放变化",
  conservation: "保守稳定",
  selfEnhancement: "自我提升",
  selfTranscendence: "自我超越",
};

function average(values: number[]) {
  return values.reduce((sum, value) => sum + value, 0) / values.length;
}

function scoreItems(answers: string[], items: number[]) {
  return average(items.map((item) => Number(answers[item - 1] || 1)));
}

export function calculateSchwartzResults(answers: string[]) {
  const valueScores = Object.fromEntries(
    Object.entries(valueItems).map(([value, items]) => [
      value,
      scoreItems(answers, items),
    ]),
  ) as Record<SchwartzValue, number>;

  const higherOrderScores: Record<SchwartzHigherOrder, number> = {
    opennessToChange: average([
      valueScores.selfDirection,
      valueScores.stimulation,
      valueScores.hedonism,
    ]),
    conservation: average([
      valueScores.security,
      valueScores.conformity,
      valueScores.tradition,
    ]),
    selfEnhancement: average([
      valueScores.achievement,
      valueScores.power,
      valueScores.hedonism,
    ]),
    selfTranscendence: average([
      valueScores.benevolence,
      valueScores.universalism,
    ]),
  };

  const rankedValues = (Object.keys(valueScores) as SchwartzValue[])
    .map((id) => ({
      id,
      name: valueNames[id],
      score: valueScores[id],
    }))
    .sort((a, b) => b.score - a.score);

  const rankedHigherOrders = (Object.keys(higherOrderScores) as SchwartzHigherOrder[])
    .map((id) => ({
      id,
      name: higherOrderNames[id],
      score: higherOrderScores[id],
    }))
    .sort((a, b) => b.score - a.score);

  return {
    valueScores,
    higherOrderScores,
    rankedValues,
    rankedHigherOrders,
  };
}
