import fs from "fs";
import path from "path";
import { CharacterMap, Character, ClassKey, Nation, AccountMap, AccountData } from "../types";

const CHARS_PATH    = path.join(__dirname, "../../data/characters.json");
const ACCOUNTS_PATH = path.join(__dirname, "../../data/accounts.json");

let _chars: CharacterMap    = {};
let _accounts: AccountMap   = {};

export function loadCharacters(): void {
  try { _chars = JSON.parse(fs.readFileSync(CHARS_PATH, "utf8")); }
  catch { _chars = {}; }
  try { _accounts = JSON.parse(fs.readFileSync(ACCOUNTS_PATH, "utf8")); }
  catch { _accounts = {}; }
}

function saveCharacters(): void {
  fs.writeFileSync(CHARS_PATH, JSON.stringify(_chars, null, 2));
}

function saveAccounts(): void {
  fs.writeFileSync(ACCOUNTS_PATH, JSON.stringify(_accounts, null, 2));
}

export function getCharacters(userKey: string): Character[] {
  return _chars[userKey]?.characters ?? [];
}

export function getActiveCharacter(userKey: string): Character | null {
  return getCharacters(userKey).find((c) => c.active) ?? null;
}

export function getCharacterByName(userKey: string, name: string): Character | null {
  return getCharacters(userKey).find((c) => c.name.toLowerCase() === name.toLowerCase()) ?? null;
}

export function getCharacterByClass(userKey: string, cls: ClassKey): Character | null {
  // Returns the active character of that class, or first found
  const chars = getCharacters(userKey).filter((c) => c.class === cls);
  return chars.find((c) => c.active) ?? chars[0] ?? null;
}

export function addCharacter(userKey: string, char: Omit<Character, "active">): boolean {
  if (!_chars[userKey]) _chars[userKey] = { characters: [] };
  const exists = _chars[userKey].characters.some((c) => c.name.toLowerCase() === char.name.toLowerCase());
  if (exists) return false;
  // If no active character, set this one as active
  const hasActive = _chars[userKey].characters.some((c) => c.active);
  _chars[userKey].characters.push({ ...char, active: !hasActive });
  saveCharacters();
  return true;
}

export function removeCharacter(userKey: string, name: string): boolean {
  if (!_chars[userKey]) return false;
  const before = _chars[userKey].characters.length;
  _chars[userKey].characters = _chars[userKey].characters.filter(
    (c) => c.name.toLowerCase() !== name.toLowerCase()
  );
  if (_chars[userKey].characters.length === before) return false;
  // If we removed the active one, set the first remaining as active
  if (!_chars[userKey].characters.some((c) => c.active) && _chars[userKey].characters.length > 0) {
    _chars[userKey].characters[0].active = true;
  }
  saveCharacters();
  return true;
}

export function setActiveCharacter(userKey: string, name: string): boolean {
  const chars = _chars[userKey]?.characters;
  if (!chars) return false;
  const target = chars.find((c) => c.name.toLowerCase() === name.toLowerCase());
  if (!target) return false;
  chars.forEach((c) => (c.active = false));
  target.active = true;
  saveCharacters();
  return true;
}

export function setCharacterNation(userKey: string, name: string, nation: Nation): boolean {
  const char = getCharacterByName(userKey, name);
  if (!char) return false;
  char.nation = nation;
  saveCharacters();
  return true;
}

export function setCharacterStats(
  userKey: string,
  name: string,
  stats: { atk?: number; def?: number; heal?: number }
): boolean {
  const char = getCharacterByName(userKey, name);
  if (!char) return false;
  if (!char.stats) char.stats = {};
  Object.assign(char.stats, stats);
  saveCharacters();
  return true;
}

// ─── Account data ─────────────────────────────────────────────────────────────
export function getAccountData(userKey: string): AccountData {
  return _accounts[userKey] ?? {};
}

export function setAccountData(userKey: string, data: Partial<AccountData>): void {
  if (!_accounts[userKey]) _accounts[userKey] = {};
  Object.assign(_accounts[userKey], data);
  saveAccounts();
}
