import 'package:flutter/foundation.dart';
import '../network/api_client.dart';

/// 获取权益类型的中文名称（公共方法）
String getAllocationTypeName(String allocationType) {
  switch (allocationType) {
    case 'SHARE_RIGHT':
      return '分享权益';
    case 'PROVINCE_AREA_RIGHT':
      return '省区域权益';
    case 'PROVINCE_TEAM_RIGHT':
      return '省团队权益';
    case 'CITY_AREA_RIGHT':
      return '市区域权益';
    case 'CITY_TEAM_RIGHT':
      return '市团队权益';
    case 'COMMUNITY_RIGHT':
      return '社区权益';
    default:
      return allocationType;
  }
}

/// 待领取奖励条目 (从 GET /rewards/pending 获取)
class PendingRewardItem {
  final String id;
  final String rightType;
  final double usdtAmount;
  final double hashpowerAmount;
  final DateTime createdAt;
  final DateTime expireAt;
  final int remainingTimeMs;
  final String sourceOrderNo;
  final String? sourceAccountSequence;  // 触发奖励的用户账户序列号
  final String memo;

  PendingRewardItem({
    required this.id,
    required this.rightType,
    required this.usdtAmount,
    required this.hashpowerAmount,
    required this.createdAt,
    required this.expireAt,
    required this.remainingTimeMs,
    required this.sourceOrderNo,
    this.sourceAccountSequence,
    required this.memo,
  });

  factory PendingRewardItem.fromJson(Map<String, dynamic> json) {
    return PendingRewardItem(
      id: json['id']?.toString() ?? '',
      rightType: json['rightType'] ?? '',
      usdtAmount: (json['usdtAmount'] ?? 0).toDouble(),
      hashpowerAmount: (json['hashpowerAmount'] ?? 0).toDouble(),
      createdAt: DateTime.tryParse(json['createdAt'] ?? '') ?? DateTime.now(),
      expireAt: DateTime.tryParse(json['expireAt'] ?? '') ?? DateTime.now(),
      remainingTimeMs: (json['remainingTimeMs'] ?? 0).toInt(),
      sourceOrderNo: json['sourceOrderNo'] ?? '',
      sourceAccountSequence: json['sourceAccountSequence'],
      memo: json['memo'] ?? '',
    );
  }

  /// 计算剩余秒数
  int get remainingSeconds => (remainingTimeMs / 1000).round();

  /// 获取权益类型的中文名称
  String get rightTypeName => getAllocationTypeName(rightType);
}

/// 可结算奖励条目 (从 GET /rewards/settleable 获取)
class SettleableRewardItem {
  final String id;
  final String rightType;
  final double usdtAmount;
  final double hashpowerAmount;
  final DateTime createdAt;
  final DateTime? claimedAt;
  final String sourceOrderNo;
  final String? sourceAccountSequence;  // 触发奖励的用户账户序列号
  final String memo;

  SettleableRewardItem({
    required this.id,
    required this.rightType,
    required this.usdtAmount,
    required this.hashpowerAmount,
    required this.createdAt,
    this.claimedAt,
    required this.sourceOrderNo,
    this.sourceAccountSequence,
    required this.memo,
  });

  factory SettleableRewardItem.fromJson(Map<String, dynamic> json) {
    return SettleableRewardItem(
      id: json['id']?.toString() ?? '',
      rightType: json['rightType'] ?? '',
      usdtAmount: (json['usdtAmount'] ?? 0).toDouble(),
      hashpowerAmount: (json['hashpowerAmount'] ?? 0).toDouble(),
      createdAt: DateTime.tryParse(json['createdAt'] ?? '') ?? DateTime.now(),
      claimedAt: json['claimedAt'] != null ? DateTime.tryParse(json['claimedAt']) : null,
      sourceOrderNo: json['sourceOrderNo'] ?? '',
      sourceAccountSequence: json['sourceAccountSequence'],
      memo: json['memo'] ?? '',
    );
  }

  /// 获取权益类型的中文名称
  String get rightTypeName => getAllocationTypeName(rightType);
}

/// 已过期奖励条目 (从 GET /wallet/expired-rewards 获取)
class ExpiredRewardItem {
  final String id;
  final String allocationType;
  final double usdtAmount;
  final double hashpowerAmount;
  final DateTime createdAt;
  final DateTime expiredAt;
  final String sourceOrderId;

  ExpiredRewardItem({
    required this.id,
    required this.allocationType,
    required this.usdtAmount,
    required this.hashpowerAmount,
    required this.createdAt,
    required this.expiredAt,
    required this.sourceOrderId,
  });

  factory ExpiredRewardItem.fromJson(Map<String, dynamic> json) {
    return ExpiredRewardItem(
      id: json['id']?.toString() ?? '',
      allocationType: json['allocationType'] ?? '',
      usdtAmount: (json['usdtAmount'] ?? 0).toDouble(),
      hashpowerAmount: (json['hashpowerAmount'] ?? 0).toDouble(),
      createdAt: DateTime.tryParse(json['createdAt'] ?? '') ?? DateTime.now(),
      expiredAt: DateTime.tryParse(json['expiredAt'] ?? '') ?? DateTime.now(),
      sourceOrderId: json['sourceOrderId'] ?? '',
    );
  }

  /// 获取权益类型的中文名称
  String get allocationTypeName => getAllocationTypeName(allocationType);

  /// 获取权益类型的中文名称（别名，与 PendingRewardItem/SettleableRewardItem 保持一致）
  String get rightTypeName => allocationTypeName;
}

/// 结算到余额结果
class SettleToBalanceResult {
  final bool success;
  final String? settlementId;
  final double settledUsdtAmount;
  final double settledHashpowerAmount;
  final int rewardCount;
  final Map<String, double>? breakdown;
  final double? balanceAfter;
  final String? error;

  SettleToBalanceResult({
    required this.success,
    this.settlementId,
    required this.settledUsdtAmount,
    required this.settledHashpowerAmount,
    required this.rewardCount,
    this.breakdown,
    this.balanceAfter,
    this.error,
  });

  factory SettleToBalanceResult.fromJson(Map<String, dynamic> json) {
    Map<String, double>? breakdown;
    if (json['breakdown'] != null) {
      breakdown = (json['breakdown'] as Map<String, dynamic>).map(
        (key, value) => MapEntry(key, (value ?? 0).toDouble()),
      );
    }

    return SettleToBalanceResult(
      success: json['success'] ?? false,
      settlementId: json['settlementId'],
      settledUsdtAmount: (json['settledUsdtAmount'] ?? 0).toDouble(),
      settledHashpowerAmount: (json['settledHashpowerAmount'] ?? 0).toDouble(),
      rewardCount: (json['rewardCount'] ?? 0).toInt(),
      breakdown: breakdown,
      balanceAfter: json['balanceAfter']?.toDouble(),
      error: json['error'],
    );
  }
}

/// 结算历史记录条目 (从 GET /rewards/settlement-history 获取)
class SettlementHistoryItem {
  final String id;
  final double usdtAmount;
  final double hashpowerAmount;
  final String settleCurrency;
  final double receivedAmount;
  final String? swapTxHash;
  final double? swapRate;
  final String status;
  final DateTime createdAt;
  final DateTime? completedAt;
  final int rewardEntryCount;

  SettlementHistoryItem({
    required this.id,
    required this.usdtAmount,
    required this.hashpowerAmount,
    required this.settleCurrency,
    required this.receivedAmount,
    this.swapTxHash,
    this.swapRate,
    required this.status,
    required this.createdAt,
    this.completedAt,
    required this.rewardEntryCount,
  });

  factory SettlementHistoryItem.fromJson(Map<String, dynamic> json) {
    return SettlementHistoryItem(
      id: json['id']?.toString() ?? '',
      usdtAmount: (json['usdtAmount'] ?? 0).toDouble(),
      hashpowerAmount: (json['hashpowerAmount'] ?? 0).toDouble(),
      settleCurrency: json['settleCurrency'] ?? '',
      receivedAmount: (json['receivedAmount'] ?? 0).toDouble(),
      swapTxHash: json['swapTxHash'],
      swapRate: json['swapRate']?.toDouble(),
      status: json['status'] ?? '',
      createdAt: DateTime.tryParse(json['createdAt'] ?? '') ?? DateTime.now(),
      completedAt: json['completedAt'] != null ? DateTime.tryParse(json['completedAt']) : null,
      rewardEntryCount: (json['rewardEntryCount'] ?? 0).toInt(),
    );
  }

  /// 获取状态的中文名称
  String get statusName {
    switch (status) {
      case 'SUCCESS':
        return '成功';
      case 'PENDING':
        return '处理中';
      case 'FAILED':
        return '失败';
      default:
        return status;
    }
  }
}

/// 结算历史分页结果
class SettlementHistoryResult {
  final List<SettlementHistoryItem> data;
  final int page;
  final int pageSize;
  final int total;

  SettlementHistoryResult({
    required this.data,
    required this.page,
    required this.pageSize,
    required this.total,
  });

  factory SettlementHistoryResult.fromJson(Map<String, dynamic> json) {
    final dataList = json['data'] as List<dynamic>? ?? [];
    final pagination = json['pagination'] as Map<String, dynamic>? ?? {};

    return SettlementHistoryResult(
      data: dataList
          .map((item) => SettlementHistoryItem.fromJson(item as Map<String, dynamic>))
          .toList(),
      page: (pagination['page'] ?? 1).toInt(),
      pageSize: (pagination['pageSize'] ?? 20).toInt(),
      total: (pagination['total'] ?? 0).toInt(),
    );
  }

  bool get hasMore => page * pageSize < total;
}

/// 奖励汇总信息 (从 reward-service 获取)
class RewardSummary {
  final double pendingUsdt;
  final double pendingHashpower;
  final DateTime? pendingExpireAt;
  final int pendingRemainingTimeMs;
  final double settleableUsdt;
  final double settleableHashpower;
  final double settledTotalUsdt;
  final double settledTotalHashpower;
  final double expiredTotalUsdt;
  final double expiredTotalHashpower;

  RewardSummary({
    required this.pendingUsdt,
    required this.pendingHashpower,
    this.pendingExpireAt,
    required this.pendingRemainingTimeMs,
    required this.settleableUsdt,
    required this.settleableHashpower,
    required this.settledTotalUsdt,
    required this.settledTotalHashpower,
    required this.expiredTotalUsdt,
    required this.expiredTotalHashpower,
  });

  factory RewardSummary.fromJson(Map<String, dynamic> json) {
    return RewardSummary(
      pendingUsdt: (json['pendingUsdt'] ?? 0).toDouble(),
      pendingHashpower: (json['pendingHashpower'] ?? 0).toDouble(),
      pendingExpireAt: json['pendingExpireAt'] != null
          ? DateTime.tryParse(json['pendingExpireAt'])
          : null,
      pendingRemainingTimeMs: (json['pendingRemainingTimeMs'] ?? 0).toInt(),
      settleableUsdt: (json['settleableUsdt'] ?? 0).toDouble(),
      settleableHashpower: (json['settleableHashpower'] ?? 0).toDouble(),
      settledTotalUsdt: (json['settledTotalUsdt'] ?? 0).toDouble(),
      settledTotalHashpower: (json['settledTotalHashpower'] ?? 0).toDouble(),
      expiredTotalUsdt: (json['expiredTotalUsdt'] ?? 0).toDouble(),
      expiredTotalHashpower: (json['expiredTotalHashpower'] ?? 0).toDouble(),
    );
  }

  /// 计算剩余秒数
  int get pendingRemainingSeconds => (pendingRemainingTimeMs / 1000).round();
}

/// 奖励服务
///
/// 直接调用 reward-service 的 API 获取奖励数据
/// 不再通过 wallet-service 中转
class RewardService {
  final ApiClient _apiClient;

  RewardService({required ApiClient apiClient}) : _apiClient = apiClient;

  /// 获取我的奖励汇总
  ///
  /// 调用 GET /rewards/summary (reward-service)
  Future<RewardSummary> getMyRewardSummary() async {
    try {
      debugPrint('[RewardService] ========== 获取奖励汇总 ==========');
      debugPrint('[RewardService] 请求: GET /rewards/summary');

      final response = await _apiClient.get('/rewards/summary');

      debugPrint('[RewardService] 响应状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应数据类型: ${response.data.runtimeType}');

      if (response.statusCode == 200) {
        final responseData = response.data as Map<String, dynamic>;
        debugPrint('[RewardService] 原始响应数据: $responseData');

        // API 返回格式: { success: true, data: {...}, timestamp: "..." }
        // 需要解包内层的 data 字段
        final data = responseData['data'] as Map<String, dynamic>? ?? responseData;
        debugPrint('[RewardService] 解包后数据: $data');

        final summary = RewardSummary.fromJson(data);
        debugPrint('[RewardService] -------- 解析结果 --------');
        debugPrint('[RewardService] pendingUsdt: ${summary.pendingUsdt}');
        debugPrint('[RewardService] pendingHashpower: ${summary.pendingHashpower}');
        debugPrint('[RewardService] pendingExpireAt: ${summary.pendingExpireAt}');
        debugPrint('[RewardService] pendingRemainingTimeMs: ${summary.pendingRemainingTimeMs}');
        debugPrint('[RewardService] pendingRemainingSeconds: ${summary.pendingRemainingSeconds}');
        debugPrint('[RewardService] settleableUsdt: ${summary.settleableUsdt}');
        debugPrint('[RewardService] settleableHashpower: ${summary.settleableHashpower}');
        debugPrint('[RewardService] settledTotalUsdt: ${summary.settledTotalUsdt}');
        debugPrint('[RewardService] settledTotalHashpower: ${summary.settledTotalHashpower}');
        debugPrint('[RewardService] expiredTotalUsdt: ${summary.expiredTotalUsdt}');
        debugPrint('[RewardService] expiredTotalHashpower: ${summary.expiredTotalHashpower}');
        debugPrint('[RewardService] ================================');

        return summary;
      }

      debugPrint('[RewardService] 请求失败，状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应内容: ${response.data}');
      throw Exception('获取奖励汇总失败: ${response.statusCode}');
    } catch (e, stackTrace) {
      debugPrint('[RewardService] !!!!!!!!!! 获取奖励汇总异常 !!!!!!!!!!');
      debugPrint('[RewardService] 错误: $e');
      debugPrint('[RewardService] 堆栈: $stackTrace');
      rethrow;
    }
  }

  /// 获取待领取奖励列表
  ///
  /// 调用 GET /rewards/pending (reward-service)
  /// 返回所有待领取的奖励条目，每条包含倒计时信息
  Future<List<PendingRewardItem>> getPendingRewards() async {
    try {
      debugPrint('[RewardService] ========== 获取待领取奖励列表 ==========');
      debugPrint('[RewardService] 请求: GET /rewards/pending');

      final response = await _apiClient.get('/rewards/pending');

      debugPrint('[RewardService] 响应状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应数据类型: ${response.data.runtimeType}');

      if (response.statusCode == 200) {
        final responseData = response.data;
        debugPrint('[RewardService] 原始响应数据: $responseData');

        // API 返回格式可能是直接数组或 { data: [...] }
        List<dynamic> dataList;
        if (responseData is List) {
          dataList = responseData;
        } else if (responseData is Map<String, dynamic>) {
          dataList = responseData['data'] as List<dynamic>? ?? [];
        } else {
          dataList = [];
        }

        debugPrint('[RewardService] 解析到 ${dataList.length} 条待领取奖励');

        final items = dataList
            .map((item) => PendingRewardItem.fromJson(item as Map<String, dynamic>))
            .toList();

        for (var item in items) {
          debugPrint('[RewardService] - ${item.rightTypeName}: ${item.usdtAmount} USDT, ${item.hashpowerAmount} 算力, 剩余 ${item.remainingSeconds}s');
        }
        debugPrint('[RewardService] ================================');

        return items;
      }

      debugPrint('[RewardService] 请求失败，状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应内容: ${response.data}');
      throw Exception('获取待领取奖励列表失败: ${response.statusCode}');
    } catch (e, stackTrace) {
      debugPrint('[RewardService] !!!!!!!!!! 获取待领取奖励列表异常 !!!!!!!!!!');
      debugPrint('[RewardService] 错误: $e');
      debugPrint('[RewardService] 堆栈: $stackTrace');
      rethrow;
    }
  }

  /// 获取可结算奖励列表
  ///
  /// 调用 GET /rewards/settleable (reward-service)
  /// 返回所有可结算的奖励条目（包括权益收益和分享收益）
  Future<List<SettleableRewardItem>> getSettleableRewards() async {
    try {
      debugPrint('[RewardService] ========== 获取可结算奖励列表 ==========');
      debugPrint('[RewardService] 请求: GET /rewards/settleable');

      final response = await _apiClient.get('/rewards/settleable');

      debugPrint('[RewardService] 响应状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应数据类型: ${response.data.runtimeType}');

      if (response.statusCode == 200) {
        final responseData = response.data;
        debugPrint('[RewardService] 原始响应数据: $responseData');

        // API 返回格式可能是直接数组或 { data: [...] }
        List<dynamic> dataList;
        if (responseData is List) {
          dataList = responseData;
        } else if (responseData is Map<String, dynamic>) {
          dataList = responseData['data'] as List<dynamic>? ?? [];
        } else {
          dataList = [];
        }

        debugPrint('[RewardService] 解析到 ${dataList.length} 条可结算奖励');

        final items = dataList
            .map((item) => SettleableRewardItem.fromJson(item as Map<String, dynamic>))
            .toList();

        for (var item in items) {
          debugPrint('[RewardService] - ${item.rightTypeName}: ${item.usdtAmount} USDT, ${item.hashpowerAmount} 贡献值');
        }
        debugPrint('[RewardService] ================================');

        return items;
      }

      debugPrint('[RewardService] 请求失败，状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应内容: ${response.data}');
      throw Exception('获取可结算奖励列表失败: ${response.statusCode}');
    } catch (e, stackTrace) {
      debugPrint('[RewardService] !!!!!!!!!! 获取可结算奖励列表异常 !!!!!!!!!!');
      debugPrint('[RewardService] 错误: $e');
      debugPrint('[RewardService] 堆栈: $stackTrace');
      rethrow;
    }
  }

  /// 结算到余额
  ///
  /// 调用 POST /rewards/settle-to-balance (reward-service)
  /// 将可结算收益直接转入钱包 USDT 余额（无币种兑换）
  Future<SettleToBalanceResult> settleToBalance() async {
    try {
      debugPrint('[RewardService] ========== 结算到余额 ==========');
      debugPrint('[RewardService] 请求: POST /rewards/settle-to-balance');

      final response = await _apiClient.post('/rewards/settle-to-balance');

      debugPrint('[RewardService] 响应状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应数据: ${response.data}');

      if (response.statusCode == 200 || response.statusCode == 201) {
        final responseData = response.data as Map<String, dynamic>;
        // 解包可能的 data 字段
        final data = responseData['data'] as Map<String, dynamic>? ?? responseData;
        final result = SettleToBalanceResult.fromJson(data);

        debugPrint('[RewardService] 结算结果:');
        debugPrint('[RewardService] - success: ${result.success}');
        debugPrint('[RewardService] - settlementId: ${result.settlementId}');
        debugPrint('[RewardService] - settledUsdtAmount: ${result.settledUsdtAmount}');
        debugPrint('[RewardService] - rewardCount: ${result.rewardCount}');
        debugPrint('[RewardService] - balanceAfter: ${result.balanceAfter}');
        debugPrint('[RewardService] ================================');

        return result;
      }

      debugPrint('[RewardService] 请求失败，状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应内容: ${response.data}');
      return SettleToBalanceResult(
        success: false,
        settledUsdtAmount: 0,
        settledHashpowerAmount: 0,
        rewardCount: 0,
        error: '结算失败: ${response.statusCode}',
      );
    } catch (e, stackTrace) {
      debugPrint('[RewardService] !!!!!!!!!! 结算异常 !!!!!!!!!!');
      debugPrint('[RewardService] 错误: $e');
      debugPrint('[RewardService] 堆栈: $stackTrace');
      return SettleToBalanceResult(
        success: false,
        settledUsdtAmount: 0,
        settledHashpowerAmount: 0,
        rewardCount: 0,
        error: e.toString(),
      );
    }
  }

  /// 获取结算历史记录
  ///
  /// 调用 GET /rewards/settlement-history (reward-service)
  /// 返回历史结算记录列表
  Future<SettlementHistoryResult> getSettlementHistory({int page = 1, int pageSize = 20}) async {
    try {
      debugPrint('[RewardService] ========== 获取结算历史记录 ==========');
      debugPrint('[RewardService] 请求: GET /rewards/settlement-history?page=$page&pageSize=$pageSize');

      final response = await _apiClient.get(
        '/rewards/settlement-history',
        queryParameters: {'page': page, 'pageSize': pageSize},
      );

      debugPrint('[RewardService] 响应状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应数据类型: ${response.data.runtimeType}');

      if (response.statusCode == 200) {
        final responseData = response.data as Map<String, dynamic>;
        debugPrint('[RewardService] 原始响应数据: $responseData');

        // 解包可能的 data 字段
        final data = responseData['data'] != null && responseData['pagination'] == null
            ? responseData['data'] as Map<String, dynamic>
            : responseData;

        final result = SettlementHistoryResult.fromJson(data);
        debugPrint('[RewardService] 解析到 ${result.data.length} 条结算记录');
        debugPrint('[RewardService] 分页: page=${result.page}, pageSize=${result.pageSize}, total=${result.total}');
        debugPrint('[RewardService] ================================');

        return result;
      }

      debugPrint('[RewardService] 请求失败，状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应内容: ${response.data}');
      throw Exception('获取结算历史记录失败: ${response.statusCode}');
    } catch (e, stackTrace) {
      debugPrint('[RewardService] !!!!!!!!!! 获取结算历史记录异常 !!!!!!!!!!');
      debugPrint('[RewardService] 错误: $e');
      debugPrint('[RewardService] 堆栈: $stackTrace');
      rethrow;
    }
  }

  /// 获取已过期奖励列表
  ///
  /// 调用 GET /wallet/expired-rewards (wallet-service)
  /// 返回所有已过期的奖励条目（24h未领取）
  Future<List<ExpiredRewardItem>> getExpiredRewards() async {
    try {
      debugPrint('[RewardService] ========== 获取已过期奖励列表 ==========');
      debugPrint('[RewardService] 请求: GET /wallet/expired-rewards');

      final response = await _apiClient.get('/wallet/expired-rewards');

      debugPrint('[RewardService] 响应状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应数据类型: ${response.data.runtimeType}');

      if (response.statusCode == 200) {
        final responseData = response.data;
        debugPrint('[RewardService] 原始响应数据: $responseData');

        // API 返回格式可能是直接数组或 { data: [...] }
        List<dynamic> dataList;
        if (responseData is List) {
          dataList = responseData;
        } else if (responseData is Map<String, dynamic>) {
          dataList = responseData['data'] as List<dynamic>? ?? [];
        } else {
          dataList = [];
        }

        debugPrint('[RewardService] 解析到 ${dataList.length} 条已过期奖励');

        final items = dataList
            .map((item) => ExpiredRewardItem.fromJson(item as Map<String, dynamic>))
            .toList();

        for (var item in items) {
          debugPrint('[RewardService] - ${item.allocationTypeName}: ${item.usdtAmount} USDT, ${item.hashpowerAmount} 算力');
        }
        debugPrint('[RewardService] ================================');

        return items;
      }

      debugPrint('[RewardService] 请求失败，状态码: ${response.statusCode}');
      debugPrint('[RewardService] 响应内容: ${response.data}');
      throw Exception('获取已过期奖励列表失败: ${response.statusCode}');
    } catch (e, stackTrace) {
      debugPrint('[RewardService] !!!!!!!!!! 获取已过期奖励列表异常 !!!!!!!!!!');
      debugPrint('[RewardService] 错误: $e');
      debugPrint('[RewardService] 堆栈: $stackTrace');
      rethrow;
    }
  }
}
