import { Injectable } from '@nestjs/common';
import { createHash } from 'crypto';

/**
 * employeeSlug 规范化服务
 *
 * 规则（PRD §核心业务约束）：
 * ① 全部转小写
 * ② [^a-z0-9-] 字符替换为 -
 * ③ 连续 - 合并为单个
 * ④ 去掉首尾 -
 * ⑤ 若长度 > 20 字符 → 取前 17 + 原 mailNickname 的 SHA1 前 3 位
 * ⑥ 规范化后撞已存在的 slug 时由调用方加数字后缀（本服务不查 DB）
 *
 * employeeSlug 首次入库后**终身冻结**，本服务仅做"原始 mailNickname → 候选 slug"
 * 的纯字符串变换，**不查 DB**。冻结由 binding 表 unique 约束 + 应用层 UPSERT 保证。
 */
@Injectable()
export class InternalAppSlugService {
  /** 保留字白名单（PRD §核心业务约束）—— app slug 不能撞，但 employeeSlug 同样禁用 */
  static readonly RESERVED_SLUGS = new Set([
    'admin',
    'api',
    'auth',
    'callback',
    'health',
    'login',
    'logout',
    'mcp',
    'oauth',
    'sso',
    'static',
    'assets',
    '_internal',
    'internal-app',
    'apps',
    'www',
  ]);

  /**
   * 把 Entra ID mailNickname 规范化为候选 employeeSlug。
   * 返回的 slug 满足：[a-z0-9-]，3-20 字符，首尾非 -。
   */
  normalizeEmployeeSlug(mailNickname: string): string {
    let slug = mailNickname
      .toLowerCase()
      .replace(/[^a-z0-9-]/g, '-')
      .replace(/-+/g, '-')
      .replace(/^-|-$/g, '');

    if (slug.length > 20) {
      const hashSuffix = createHash('sha1')
        .update(mailNickname)
        .digest('hex')
        .slice(0, 3);
      slug = `${slug.slice(0, 17)}${hashSuffix}`;
    }

    return slug;
  }

  /** app slug 校验（PRD §核心业务约束）：3-22 字符 [a-z0-9-]，首尾非 - */
  validateAppSlug(slug: string): { ok: true } | { ok: false; reason: string } {
    // 强制最少 3 字符：开头 [a-z0-9] + 中间 [a-z0-9-]{1,20} + 结尾 [a-z0-9]
    if (!/^[a-z0-9][a-z0-9-]{1,20}[a-z0-9]$/.test(slug)) {
      return {
        ok: false,
        reason: 'app 名必须是 3-22 个小写字母/数字/中划线，首尾不能是中划线',
      };
    }
    if (InternalAppSlugService.RESERVED_SLUGS.has(slug)) {
      return { ok: false, reason: `app 名 "${slug}" 是平台保留字，请换一个` };
    }
    return { ok: true };
  }
}
