/**
 * CharacterRegistry — central lookup for Character objects.
 *
 * Usage:
 *   import { CharacterRegistry } from "@registry/CharacterRegistry";
 *
 *   const char = CharacterRegistry.find("«Flash»");
 *   const chars = CharacterRegistry.forUser("flash");
 *   const active = CharacterRegistry.getActive("flash");
 */

 import fs from "fs";
 import path from "path";
 import { Character, UserKey, CharName } from "@types";
 import { Paths } from "@helpers/paths";
 
  const CHARS_PATH = Paths.data("characters.json");
 
  let _cache: Record<string, { characters: Character[] }> | null = null;
 
  function loadChars(): Record<string, { characters: Character[] }> {
    if (!_cache) {
      try { 
        _cache = JSON.parse(fs.readFileSync(CHARS_PATH, "utf8"));
        console.log("[CharacterRegistry] cache miss — loading from disk");
      }
      catch { _cache = {}; }
    }
    
    return _cache!;
  }
 
 export const CharacterRegistry = {
   /**
    * Find a character by name across all users.
    * Character names are unique across users (enforced by conflict system).
    */
   find(charName: CharName): Character | null {
     const chars = loadChars();
     for (const data of Object.values(chars)) {
       const found = data.characters?.find(
         (c) => c.name.toLowerCase() === charName.toLowerCase()
       );
       if (found) return found;
     }
     return null;
   },

    all(): Character[] {
      const chars = loadChars();
      return Object.values(chars).flatMap((data: any) => data.characters ?? []);
    },
 
   /**
    * Find a character by name for a specific user.
    */
   findForUser(userKey: UserKey, charName: CharName): Character | null {
     const chars = loadChars();
     return chars[userKey]?.characters?.find(
       (c) => c.name.toLowerCase() === charName.toLowerCase()
     ) ?? null;
   },
 
   /**
    * Get all characters for a user.
    */
   forUser(userKey: UserKey): Character[] {
     const chars = loadChars();
     return chars[userKey]?.characters ?? [];
   },
 
   /**
    * Get the active character for a user (from characters.json only, no borrow).
    * For effective char (including borrows), use getEffectiveCharacter from borrow.ts.
    */
   getActive(userKey: UserKey): Character | null {
     return CharacterRegistry.forUser(userKey).find((c) => c.active) ?? null;
   },
 
   /**
    * Get all characters shared with a given user across all owners.
    */
   sharedWith(userKey: UserKey): { char: Character; ownerKey: UserKey }[] {
     const chars  = loadChars();
     const result: { char: Character; ownerKey: UserKey }[] = [];
     for (const [ownerKey, data] of Object.entries(chars)) {
       if (ownerKey === userKey) continue;
       for (const char of data.characters ?? []) {
         if (char.sharedWith?.includes(userKey)) {
           result.push({ char, ownerKey });
         }
       }
     }
     return result;
   },

  invalidateCache(): void {
    _cache = null;
  },
 };