import '../network/api_client.dart';

// ============================================================
// ReferralService — 推荐/邀请系统客户端
//
// 对接后端 referral-service（端口 3013，经 Kong 网关 :8080 转发）
//
// 端点一览：
//   GET  /api/v1/referral/my          获取当前用户的推荐信息（需 JWT）
//   GET  /api/v1/referral/validate    验证推荐码是否有效（公开）
//   GET  /api/v1/referral/direct      获取直接推荐列表（需 JWT）
//
// 推荐码格式：GNX + 5 位无歧义字符（排除 0/O/I/1），示例：GNXAB2C3
// 推荐链：每个用户拥有唯一推荐码，可追溯至多 50 层祖先节点
// ============================================================

/// 当前用户的推荐关系数据
///
/// 对应后端 [GET /api/v1/referral/my] 返回的 `data` 字段。
///
/// 后端响应示例：
/// ```json
/// {
///   "code": 0,
///   "data": {
///     "userId": "uuid-...",
///     "referralCode": "GNXAB2C3",
///     "referrerId": "uuid-... | null",
///     "usedCode": "GNXPARENT | null",
///     "directReferralCount": 5,
///     "totalTeamCount": 23
///   }
/// }
/// ```
class ReferralInfo {
  /// 本用户的专属推荐码（格式：GNXxxxxx，固定 8 位大写）
  final String referralCode;

  /// 直接推荐人数（通过本人推荐码注册的用户数量）
  final int directReferralCount;

  /// 团队总人数（整条推荐链下的所有层级用户总数）
  final int totalTeamCount;

  /// 推荐人 userId（若无人推荐则为 null）
  final String? referrerId;

  /// 注册时填写的推荐码（即 referrerId 对应的 referralCode，冗余存储方便展示）
  final String? usedCode;

  const ReferralInfo({
    required this.referralCode,
    required this.directReferralCount,
    required this.totalTeamCount,
    this.referrerId,
    this.usedCode,
  });

  factory ReferralInfo.fromJson(Map<String, dynamic> json) {
    return ReferralInfo(
      referralCode: json['referralCode'] as String,
      directReferralCount: json['directReferralCount'] as int? ?? 0,
      totalTeamCount: json['totalTeamCount'] as int? ?? 0,
      referrerId: json['referrerId'] as String?,
      usedCode: json['usedCode'] as String?,
    );
  }

  @override
  String toString() =>
      'ReferralInfo(code=$referralCode, direct=$directReferralCount, team=$totalTeamCount)';
}

/// 推荐服务 — 单例
///
/// 用法：
/// ```dart
/// final info = await ReferralService.instance.getMyInfo();
/// print(info.referralCode); // e.g. GNXAB2C3
/// ```
///
/// 注意：所有方法均需要 ApiClient 携带有效 JWT；
/// 若未登录或 token 过期，将抛出 DioException（401）。
class ReferralService {
  static final ReferralService _instance = ReferralService._();
  static ReferralService get instance => _instance;
  ReferralService._();

  final _api = ApiClient.instance;

  // ── 查询 ─────────────────────────────────────────────────────────────────

  /// 获取当前用户的推荐信息
  ///
  /// 包含：专属推荐码、直接推荐人数、团队总人数、是否被推荐等。
  ///
  /// - 需要登录（请求头携带 Bearer Token）
  /// - 首次登录即自动在后端创建推荐档案（由 Kafka 事件触发）
  ///
  /// Throws [DioException] on network error or 401/403.
  Future<ReferralInfo> getMyInfo() async {
    final resp = await _api.get('/api/v1/referral/my');
    final data = resp.data['data'] as Map<String, dynamic>;
    return ReferralInfo.fromJson(data);
  }

  /// 验证推荐码是否有效（公开接口，无需登录）
  ///
  /// 用于注册页实时校验邀请码。
  ///
  /// 后端响应：`{ "code": 0, "data": { "valid": true/false } }`
  ///
  /// Returns `false` on any error (avoid blocking registration flow).
  Future<bool> validateCode(String code) async {
    try {
      final resp = await _api.get(
        '/api/v1/referral/validate',
        queryParameters: {'code': code.toUpperCase()},
      );
      final data = resp.data['data'] as Map<String, dynamic>;
      return data['valid'] == true;
    } catch (_) {
      return false;
    }
  }

  /// 获取直接推荐列表（分页）
  ///
  /// 每条记录包含被推荐用户的 userId、注册时间、推荐码等基本信息。
  ///
  /// - [offset] 分页偏移，从 0 开始
  /// - [limit]  每页条数，最大 50
  ///
  /// 后端响应 `data` 字段示例：
  /// ```json
  /// {
  ///   "items": [ { "userId": "...", "referralCode": "...", "createdAt": "..." } ],
  ///   "total": 5
  /// }
  /// ```
  Future<List<Map<String, dynamic>>> getDirectReferrals({
    int offset = 0,
    int limit = 20,
  }) async {
    final resp = await _api.get('/api/v1/referral/direct', queryParameters: {
      'offset': offset,
      'limit': limit,
    });
    final data = resp.data['data'] as Map<String, dynamic>;
    return (data['items'] as List).cast<Map<String, dynamic>>();
  }
}
