import Life from "../../../src/life.js";
import { getGrade, getRate } from "../../../src/functions/addition.js";
import { summary } from "../../../src/functions/summary.js";
import { installEventBus } from "../../../src/runtime/shared.js";
import achievementUrl from "../../../data/achievement.json?url";
import ageUrl from "../../../data/age.json?url";
import eventsUrl from "../../../data/events.json?url";
import specialThanksUrl from "../../../data/specialthanks.json?url";
import talentsUrl from "../../../data/talents.json?url";

const LEGACY_DATASET_URLS = {
  achievement: achievementUrl,
  age: ageUrl,
  events: eventsUrl,
  specialthanks: specialThanksUrl,
  talents: talentsUrl,
};
const legacyDatasetCache = new Map();

export const LEGACY_STAT_DEFINITIONS = [
  { id: "CHR", label: "Charm", min: 0, max: 10, initial: 0 },
  { id: "INT", label: "Intelligence", min: 0, max: 10, initial: 0 },
  { id: "STR", label: "Strength", min: 0, max: 10, initial: 0 },
  { id: "MNY", label: "Money", min: 0, max: 10, initial: 0 },
  { id: "SPR", label: "Spirit", min: 0, max: 10, initial: 5 },
];

export const LEGACY_SUMMARY_ORDER = [
  "CHR",
  "INT",
  "STR",
  "MNY",
  "SPR",
  "AGE",
  "SUM",
];

export const LEGACY_SUMMARY_LABELS = {
  CHR: "Charm",
  INT: "Intelligence",
  STR: "Strength",
  MNY: "Money",
  SPR: "Spirit",
  AGE: "Age",
  SUM: "Overall",
};

export const LEGACY_OPPORTUNITY_LABELS = {
  START: "Start",
  TRAJECTORY: "Trajectory",
  SUMMARY: "Summary",
  END: "End",
};

const LEGACY_RATE_COLORS = {
  0: "White",
  1: "Blue",
  2: "Purple",
  3: "Orange",
};

function cloneValue(value) {
  if (typeof structuredClone === "function") {
    return structuredClone(value);
  }

  return JSON.parse(JSON.stringify(value));
}

async function readLegacyJson(fileName) {
  if (!legacyDatasetCache.has(fileName)) {
    const url = LEGACY_DATASET_URLS[fileName];
    if (!url) {
      throw new Error(`Unknown legacy dataset: ${fileName}`);
    }

    const response = await fetch(url);
    legacyDatasetCache.set(fileName, await response.json());
  }

  const dataset = legacyDatasetCache.get(fileName);
  if (!dataset) {
    throw new Error(`Unknown legacy dataset: ${fileName}`);
  }

  return cloneValue(dataset);
}

export function installLegacyBrowserRuntime() {
  installEventBus();
  globalThis.json = async (fileName) => readLegacyJson(fileName);
}

export function createLegacyLife() {
  installLegacyBrowserRuntime();
  return new Life();
}

function formatLegacyRateDetail(type, value) {
  const [colorKey, multiplier] = Object.entries(getRate(type, value))[0] ?? [];
  if (!colorKey || typeof multiplier !== "number") {
    return "";
  }

  return `Legacy bonus: ${LEGACY_RATE_COLORS[colorKey] ?? colorKey} draw rate x${multiplier}`;
}

export function buildLegacyTotalCards(totals) {
  return [
    {
      id: "times",
      label: "Remakes",
      value: `${totals.times}`,
      detail: formatLegacyRateDetail("times", totals.times),
      grade: getGrade("times", totals.times),
    },
    {
      id: "achievement",
      label: "Achievements",
      value: `${totals.achievement}`,
      detail: formatLegacyRateDetail("achievement", totals.achievement),
      grade: getGrade("achievement", totals.achievement),
    },
    {
      id: "talentRate",
      label: "Talent Collection",
      value: `${Math.floor(totals.talentRate * 100)}%`,
      detail: "Share of legacy talents seen across all runs.",
      grade: getGrade("talentRate", totals.talentRate),
    },
    {
      id: "eventRate",
      label: "Event Collection",
      value: `${Math.floor(totals.eventRate * 100)}%`,
      detail: "Share of legacy events triggered across all runs.",
      grade: getGrade("eventRate", totals.eventRate),
    },
  ];
}

export function buildLegacySummary(summaryValues) {
  return LEGACY_SUMMARY_ORDER.map((type) => {
    const value = summaryValues[type];
    const result = summary(type, value);

    return {
      type,
      label: LEGACY_SUMMARY_LABELS[type] ?? type,
      value,
      judge: result?.judge ?? "",
      grade: result?.grade ?? 0,
    };
  });
}

export async function loadLegacySpecialThanks() {
  const entries = await readLegacyJson("specialthanks");

  return entries.map((entry) => ({
    group: entry.group === 1 ? 1 : 2,
    name: entry.name,
    comment: entry.comment ?? "",
    color: entry.color ?? "",
  }));
}

export function onLegacyAchievement(listener) {
  installLegacyBrowserRuntime();
  globalThis.$$on("achievement", listener);

  return () => {
    globalThis.$$off("achievement", listener);
  };
}
