import { readDB, withDB, readDBOnce } from '../db.js';
import { fetchPlayerInfo } from './garena.js';
import { normalizePackageId } from './pricing.js';
import { getPricingConfig } from '../config.js';

const UNVERIFIED_NICKNAME = 'Unverified';

function buildLocalPackages() {
  const config = getPricingConfig();
  return (config.packages || []).map(pkg => ({
    id: pkg.id,
    size: pkg.size,
    hasDiscount: true,
  }));
}

function buildUserRecord({ nickname = null, packages = [], purchasedPackages = [], availableLevels = [] }) {
  const normalizedPackages = Array.isArray(packages) ? packages : [];
  return {
    nickname,
    packages: normalizedPackages,
    discountedPackages: normalizedPackages
      .filter(pkg => pkg.hasDiscount)
      .map(pkg => normalizePackageId(pkg.id)),
    purchasedPackages: Array.isArray(purchasedPackages)
      ? purchasedPackages.map(normalizePackageId)
      : [],
    availableLevels: Array.isArray(availableLevels) ? availableLevels : [],
    cachedAt: new Date().toISOString(),
  };
}

function normalizeStoredUser(user) {
  const packages = Array.isArray(user.packages) ? user.packages : [];
  return {
    ...user,
    nickname: user.nickname || UNVERIFIED_NICKNAME,
    packages,
    discountedPackages: Array.isArray(user.discountedPackages)
      ? user.discountedPackages.map(normalizePackageId)
      : packages.filter(pkg => pkg.hasDiscount).map(pkg => normalizePackageId(pkg.id)),
    purchasedPackages: Array.isArray(user.purchasedPackages)
      ? user.purchasedPackages.map(normalizePackageId)
      : [],
  };
}

/**
 * Devuelve el usuario desde nuestra DB temporal (users.json).
 * Si NO existe, lo registra consultando PagoStore UNA sola vez
 * (nickname + paquetes con descuento) y lo guarda.
 *
 * Si Garena falla por cookie/seguridad, registra con catalogo local y
 * nickname API "Unverified"; invalid_id sigue bloqueado.
 *
 * Race-free: usa readDBOnce para check inicial, fetch fuera del lock,
 * y withDB para crear atómicamente (re-checkea dentro del lock).
 */
export async function getOrRegisterUser(id) {
  // 1. Siempre intentar Garena (Pagostore) primero fuera del lock
  const result = await fetchPlayerInfo(id);

  if (result.status === 'ok') {
    // 2. Garena OK: Guardar datos frescos preservando el historial de compras
    const updated = await withDB(db => {
      const existing = db.users[id];
      const freshUser = buildUserRecord({
        nickname: result.nickname,
        packages: result.packages,
        purchasedPackages: existing ? existing.purchasedPackages : [],
        availableLevels: result.availableLevels || [],
      });
      db.users[id] = freshUser;
      return normalizeStoredUser(freshUser);
    });
    return { status: 'ok', user: updated, cached: false };
  } 
  
  if (result.status === 'invalid_id') {
    return result;
  }
  
  // 3. Si Garena falla (DataDome/red) y el usuario ya existe en cache, permitir acceso en modo fallback
  const existing = await readDBOnce().then(db => db.users[id]);
  if (existing) {
    return { status: 'ok', user: normalizeStoredUser(existing), cached: true, fallback: true };
  }

  // Si no existe y Garena falla, bloquear login
  return result;
}
