import { customAlphabet } from "nanoid";
import { ulid } from "ulid";

// Crockford base32 sin caracteres ambiguos (I, L, O, U excluidos)
const alphabet = "0123456789abcdefghjkmnpqrstvwxyz";

const nanoid43 = customAlphabet(alphabet, 43);

export const ID_PREFIXES = {
  merchant: "mer",
  apiKey: "key",
  providerConfig: "pcfg",
  customer: "cus",
  paymentIntent: "pi",
  paymentAttempt: "pa",
  paymentRefund: "re",
  checkoutSession: "cs",
  webhookEndpoint: "whe",
  webhookEventOut: "evt",
  webhookEventIn: "wei",
  pricingPlan: "plan",
  invoice: "inv",
  invoiceItem: "ii",
  auditLog: "log",
  adminUser: "adu",
} as const;

export type IdPrefixKey = keyof typeof ID_PREFIXES;

/**
 * ID con prefijo de recurso + ULID time-ordered (26 chars Crockford base32).
 * Los primeros 10 chars del ULID son timestamp ms → sortable por creación
 * sin depender del índice. Lowercaseado para consistencia visual con los prefijos.
 */
export function newId(kind: IdPrefixKey): string {
  return `${ID_PREFIXES[kind]}_${ulid().toLowerCase()}`;
}

/**
 * Token público URL-safe para hosted checkout sessions y client_secrets.
 * 43 chars en base32 → ~215 bits de entropía. NO ordenado (es secreto, no ID).
 */
export function newPublicToken(): string {
  return nanoid43();
}

/**
 * Genera el body completo de una API key (lo que se le entrega al merchant una sola vez).
 * El prefix visible se guarda en DB; el body completo se hashea con bcrypt.
 */
export function newApiKeyValue(
  type: "secret" | "publishable",
  environment: "live" | "test",
): { full: string; prefix: string } {
  const typeCode = type === "secret" ? "sk" : "pk";
  const envCode = environment === "live" ? "live" : "test";
  const random = nanoid43();
  const full = `${typeCode}_${envCode}_${random}`;
  // prefix visible en dashboard: primeros 12 chars del random ⇒ identificable sin revelar
  const prefix = `${typeCode}_${envCode}_${random.slice(0, 12)}`;
  return { full, prefix };
}
