const FREE_MAX_ACCOUNTS = 1;
const PRO_MAX_ACCOUNTS = 5;
const GRACE_MS = 7 * 24 * 60 * 60 * 1000;

function executionAccounts(accounts) {
  return (Array.isArray(accounts) ? accounts : []).filter((account) => account?.historyOnly !== true);
}

function safeError(status, code, message) {
  const error = new Error(message);
  error.status = status;
  error.code = code;
  return error;
}

function lockedAccess() {
  return {
    allowed: false,
    entitlementLocked: true,
    status: 402,
    code: "pro_required",
    message: "Pro is required to use this account.",
  };
}

export function getPublicEntitlementStatus({ certificate, accounts, now = Date.now() }) {
  const configuredAccounts = executionAccounts(accounts).length;
  const expiresAtMs = Number.isSafeInteger(certificate?.exp) ? certificate.exp * 1000 : null;
  const validProCertificate = certificate?.productId === "pro_multi_account"
    && certificate?.maxAccounts === PRO_MAX_ACCOUNTS
    && expiresAtMs !== null;

  if (!validProCertificate) {
    return {
      tier: "free",
      state: "active",
      maxAccounts: FREE_MAX_ACCOUNTS,
      configuredAccounts,
      expiresAt: null,
      graceEndsAt: null,
    };
  }

  const graceEndsAtMs = expiresAtMs + GRACE_MS;
  const common = {
    configuredAccounts,
    expiresAt: new Date(expiresAtMs).toISOString(),
    graceEndsAt: new Date(graceEndsAtMs).toISOString(),
  };
  if (now < expiresAtMs) {
    return { tier: "pro", state: "active", maxAccounts: PRO_MAX_ACCOUNTS, ...common };
  }
  if (now < graceEndsAtMs) {
    return { tier: "pro", state: "grace", maxAccounts: PRO_MAX_ACCOUNTS, ...common };
  }
  return { tier: "free", state: "expired", maxAccounts: FREE_MAX_ACCOUNTS, ...common };
}

export function getAccountExecutionAccess({ accountId, accounts, entitlement }) {
  const configured = executionAccounts(accounts);
  const accountIndex = configured.findIndex((account) => account?.id === accountId);
  if (accountIndex < 0) return { allowed: false, entitlementLocked: false };
  if (accountIndex >= entitlement.maxAccounts) return lockedAccess();
  return { allowed: true, entitlementLocked: false };
}

export function assertCanAddExecutionAccount({ accounts, entitlement }) {
  if (executionAccounts(accounts).length < entitlement.maxAccounts) return;
  if (entitlement.tier === "pro") {
    throw safeError(409, "account_limit_reached", "The account limit has been reached.");
  }
  throw safeError(402, "pro_required", "Pro is required to add another account.");
}
