/**
 * SSO 错误码常量（v2.4 Entra ID SSO 登录）
 *
 * 8 个错误码：5 个核心 SSO_* + 3 个 Entra error query 映射码。
 * 完整定义见 docs/modules/organization/08-error-codes.md §「认证 / SSO 错误码」。
 *
 * 注意：`IAM_USER_SUSPENDED`（用户被禁用）走现有错误码，**不**在此 enum 中。
 */

export type SsoErrorCode =
  | 'SSO_DOMAIN_NOT_ALLOWED'
  | 'SSO_TOKEN_INVALID'
  | 'SSO_EMAIL_MISSING'
  | 'SSO_BINDING_CONFLICT'
  | 'SSO_PROVIDER_UNAVAILABLE'
  | 'SSO_USER_CANCELLED'
  | 'SSO_CONSENT_REQUIRED'
  | 'SSO_PROVIDER_REJECTED';

export const SSO_ERROR_CODES: Record<SsoErrorCode, { http: number; code: SsoErrorCode }> = {
  SSO_DOMAIN_NOT_ALLOWED: { http: 403, code: 'SSO_DOMAIN_NOT_ALLOWED' },
  SSO_TOKEN_INVALID: { http: 401, code: 'SSO_TOKEN_INVALID' },
  SSO_EMAIL_MISSING: { http: 400, code: 'SSO_EMAIL_MISSING' },
  SSO_BINDING_CONFLICT: { http: 409, code: 'SSO_BINDING_CONFLICT' },
  SSO_PROVIDER_UNAVAILABLE: { http: 503, code: 'SSO_PROVIDER_UNAVAILABLE' },
  SSO_USER_CANCELLED: { http: 403, code: 'SSO_USER_CANCELLED' },
  SSO_CONSENT_REQUIRED: { http: 403, code: 'SSO_CONSENT_REQUIRED' },
  SSO_PROVIDER_REJECTED: { http: 502, code: 'SSO_PROVIDER_REJECTED' },
};

/**
 * 业务层用的轻量异常对象。
 *
 * Controller 在 callback 捕获后转成 302 redirect 到 /login?ssoError=<CODE>，
 * **不**返 JSON body（按 PRD 决策卡：302 + body 浏览器不暴露给 JS）。
 */
export class SsoError extends Error {
  readonly code: SsoErrorCode;
  readonly http: number;
  readonly meta?: Record<string, unknown>;

  constructor(code: SsoErrorCode, message?: string, meta?: Record<string, unknown>) {
    super(message ?? code);
    this.name = 'SsoError';
    this.code = code;
    this.http = SSO_ERROR_CODES[code].http;
    this.meta = meta;
  }
}
