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

// ============================================
// [2026-02-17] 预种计划 API 服务
// ============================================
//
// 预种计划（拼种/团购计划）的 Flutter 端 API 调用服务。
// [2026-03-01] 方案调整：1887 USDT/份 × 10 份 = 18870 USDT/棵
// 用户以 1887 USDT/份参与认种，累计 10 份自动合成 1 棵树。
//
// === API 端点 ===
// 所有端点走 planting-service 的 PrePlantingModule：
// - GET  /pre-planting/config       获取预种开关状态（public controller）
// - GET  /pre-planting/eligibility  检查购买资格
// - GET  /pre-planting/position     获取预种持仓
// - GET  /pre-planting/orders       获取预种订单列表
// - GET  /pre-planting/merges       获取合并记录列表
// - GET  /pre-planting/merges/:no   获取合并详情
// - POST /pre-planting/purchase     创建预种订单（购买）
// - POST /pre-planting/sign-contract  签署合并合同
//
// === 与现有 PlantingService 的关系 ===
// 完全独立。PlantingService 处理整棵树认种（18870 USDT/棵），
// PrePlantingService 处理预种份额（1887 USDT/份）。
// 两者调用不同的 API 端点，互不影响。

/// 预种订单状态
enum PrePlantingOrderStatus {
  created,   // 已创建（待支付）
  paid,      // 已支付（算力已生效）
  merged,    // 已合并（5 份合成 1 棵树）
}

/// 预种合同签署状态
enum PrePlantingContractStatus {
  pending,   // 待签署
  signed,    // 已签署
  expired,   // 已过期
}

/// 预种开关配置
class PrePlantingConfig {
  final bool isActive;          // 预种功能是否开启
  final DateTime? activatedAt;  // 开启时间
  final String? agreementText;  // 预种协议文本（null 时使用默认）

  PrePlantingConfig({
    required this.isActive,
    this.activatedAt,
    this.agreementText,
  });

  factory PrePlantingConfig.fromJson(Map<String, dynamic> json) {
    return PrePlantingConfig(
      isActive: json['isActive'] ?? false,
      activatedAt: json['activatedAt'] != null
          ? DateTime.parse(json['activatedAt'])
          : null,
      agreementText: json['agreementText'] as String?,
    );
  }
}

/// 预种持仓信息（每用户一条）
class PrePlantingPosition {
  final int totalPortions;       // 累计购买份数（含已合并）
  final int availablePortions;   // 待合并份数（0-4）
  final int mergedPortions;      // 已合并份数
  final int totalTreesMerged;    // 已合成的树数
  final String? provinceCode;    // 省代码（首次购买时选择，后续复用）
  final String? cityCode;        // 市代码
  final String? provinceName;    // 省名称
  final String? cityName;        // 市名称
  final DateTime? firstPurchaseAt; // 首次购买时间（1 年冻结起点）

  PrePlantingPosition({
    required this.totalPortions,
    required this.availablePortions,
    required this.mergedPortions,
    required this.totalTreesMerged,
    this.provinceCode,
    this.cityCode,
    this.provinceName,
    this.cityName,
    this.firstPurchaseAt,
  });

  /// 距离下一次合并还需多少份
  int get portionsToNextMerge => availablePortions == 0 ? 5 : 5 - availablePortions;

  /// 合并进度 (0.0 - 1.0)
  double get mergeProgress => availablePortions / 5.0;

  /// 是否已选择省市（首次购买后即锁定）
  bool get hasProvinceCity => provinceCode != null && cityCode != null;

  factory PrePlantingPosition.fromJson(Map<String, dynamic> json) {
    return PrePlantingPosition(
      totalPortions: json['totalPortions'] ?? 0,
      availablePortions: json['availablePortions'] ?? 0,
      mergedPortions: json['mergedPortions'] ?? 0,
      totalTreesMerged: json['totalTreesMerged'] ?? 0,
      provinceCode: json['provinceCode'],
      cityCode: json['cityCode'],
      provinceName: json['provinceName'],
      cityName: json['cityName'],
      firstPurchaseAt: json['firstPurchaseAt'] != null
          ? DateTime.parse(json['firstPurchaseAt'])
          : null,
    );
  }
}

/// 预种订单
class PrePlantingOrder {
  final String orderNo;
  final int portionCount;        // 购买份数（通常为 1）
  final double pricePerPortion;  // 每份价格（1887 USDT）
  final double totalAmount;      // 总金额
  final PrePlantingOrderStatus status;
  final String? mergedToMergeId; // 合并后指向的 MergeId
  final DateTime? paidAt;
  final DateTime? mergedAt;
  final DateTime createdAt;

  PrePlantingOrder({
    required this.orderNo,
    required this.portionCount,
    required this.pricePerPortion,
    required this.totalAmount,
    required this.status,
    this.mergedToMergeId,
    this.paidAt,
    this.mergedAt,
    required this.createdAt,
  });

  factory PrePlantingOrder.fromJson(Map<String, dynamic> json) {
    return PrePlantingOrder(
      orderNo: json['orderNo'] ?? '',
      portionCount: json['portionCount'] ?? 1,
      pricePerPortion: (json['pricePerPortion'] ?? 1887).toDouble(),
      totalAmount: (json['totalAmount'] ?? 1887).toDouble(),
      status: _parseStatus(json['status']),
      mergedToMergeId: json['mergedToMergeId']?.toString(),
      paidAt: json['paidAt'] != null ? DateTime.parse(json['paidAt']) : null,
      mergedAt: json['mergedAt'] != null ? DateTime.parse(json['mergedAt']) : null,
      createdAt: json['createdAt'] != null
          ? DateTime.parse(json['createdAt'])
          : DateTime.now(),
    );
  }

  static PrePlantingOrderStatus _parseStatus(String? status) {
    switch (status) {
      case 'CREATED': return PrePlantingOrderStatus.created;
      case 'PAID': return PrePlantingOrderStatus.paid;
      case 'MERGED': return PrePlantingOrderStatus.merged;
      default: return PrePlantingOrderStatus.created;
    }
  }
}

/// 预种合并记录（5 份 → 1 棵树）
/// 合并来源订单详情
class MergeSourceOrder {
  final String orderNo;
  final int portionCount;
  final double totalAmount;

  MergeSourceOrder({
    required this.orderNo,
    required this.portionCount,
    required this.totalAmount,
  });

  factory MergeSourceOrder.fromJson(Map<String, dynamic> json) {
    return MergeSourceOrder(
      orderNo: json['orderNo'] ?? '',
      portionCount: json['portionCount'] ?? 1,
      totalAmount: (json['totalAmount'] ?? 0).toDouble(),
    );
  }
}

class PrePlantingMerge {
  final String mergeNo;
  final List<String> sourceOrderNos;  // 来源订单号列表
  final List<MergeSourceOrder> sourceOrders; // 来源订单详情（含份数和金额）
  final int totalPortions;            // 合并总份数（应为 10）
  final double totalAmount;           // 合并总金额（各订单实际支付之和）
  final int treeCount;                // 合并产生的树数（固定 1）
  final PrePlantingContractStatus contractStatus;
  final DateTime? contractSignedAt;
  final DateTime? miningEnabledAt;
  final String? selectedProvince;
  final String? selectedCity;
  final DateTime mergedAt;

  PrePlantingMerge({
    required this.mergeNo,
    required this.sourceOrderNos,
    this.sourceOrders = const [],
    this.totalPortions = 0,
    this.totalAmount = 0,
    required this.treeCount,
    required this.contractStatus,
    this.contractSignedAt,
    this.miningEnabledAt,
    this.selectedProvince,
    this.selectedCity,
    required this.mergedAt,
  });

  /// 是否已签约
  bool get isSigned => contractStatus == PrePlantingContractStatus.signed;

  /// 是否挖矿已开启
  bool get isMiningEnabled => miningEnabledAt != null;

  factory PrePlantingMerge.fromJson(Map<String, dynamic> json) {
    final sourceOrders = (json['sourceOrders'] as List<dynamic>?)
            ?.map((e) => MergeSourceOrder.fromJson(e as Map<String, dynamic>))
            .toList() ??
        [];
    return PrePlantingMerge(
      mergeNo: json['mergeNo'] ?? '',
      sourceOrderNos: (json['sourceOrderNos'] as List<dynamic>?)
              ?.map((e) => e.toString())
              .toList() ??
          [],
      sourceOrders: sourceOrders,
      totalPortions: json['totalPortions'] ?? sourceOrders.fold(0, (sum, o) => sum + o.portionCount),
      totalAmount: (json['totalAmount'] ?? sourceOrders.fold(0.0, (sum, o) => sum + o.totalAmount)).toDouble(),
      treeCount: json['treeCount'] ?? 1,
      contractStatus: _parseContractStatus(json['contractStatus']),
      contractSignedAt: json['contractSignedAt'] != null
          ? DateTime.parse(json['contractSignedAt'])
          : null,
      miningEnabledAt: json['miningEnabledAt'] != null
          ? DateTime.parse(json['miningEnabledAt'])
          : null,
      selectedProvince: json['selectedProvince'],
      selectedCity: json['selectedCity'],
      mergedAt: json['mergedAt'] != null
          ? DateTime.parse(json['mergedAt'])
          : DateTime.now(),
    );
  }

  static PrePlantingContractStatus _parseContractStatus(String? status) {
    switch (status) {
      case 'PENDING': return PrePlantingContractStatus.pending;
      case 'SIGNED': return PrePlantingContractStatus.signed;
      case 'EXPIRED': return PrePlantingContractStatus.expired;
      default: return PrePlantingContractStatus.pending;
    }
  }
}

/// 创建预种订单响应
class CreatePrePlantingOrderResponse {
  final String orderNo;
  final int portionCount;
  final double totalAmount;
  final double pricePerPortion;
  final bool merged;
  final String? mergeNo;

  CreatePrePlantingOrderResponse({
    required this.orderNo,
    required this.portionCount,
    required this.totalAmount,
    required this.pricePerPortion,
    this.merged = false,
    this.mergeNo,
  });

  factory CreatePrePlantingOrderResponse.fromJson(Map<String, dynamic> json) {
    return CreatePrePlantingOrderResponse(
      orderNo: json['orderNo'] ?? '',
      portionCount: json['portionCount'] ?? 1,
      totalAmount: (json['totalAmount'] ?? 1887).toDouble(),
      pricePerPortion: (json['pricePerPortion'] ?? 1887).toDouble(),
      merged: json['merged'] == true,
      mergeNo: json['mergeNo']?.toString(),
    );
  }
}

/// 预种购买资格检查结果
class PrePlantingEligibility {
  final bool canPurchase;          // 是否可以购买
  final int? maxAdditional;        // 最多还能买几份（开关关闭时的凑满限制）
  final String? message;           // 不可购买的原因说明

  PrePlantingEligibility({
    required this.canPurchase,
    this.maxAdditional,
    this.message,
  });

  factory PrePlantingEligibility.fromJson(Map<String, dynamic> json) {
    return PrePlantingEligibility(
      canPurchase: json['canPurchase'] ?? false,
      maxAdditional: json['maxAdditional'],
      message: json['message'],
    );
  }
}

// ============================================
// 预种计划 API 服务
// ============================================

/// 预种计划 API 服务
///
/// [2026-02-17] 新增：提供预种计划的所有 API 调用
///
/// 所有端点走 planting-service 的 /pre-planting/* 路由，
/// 由 PrePlantingModule 的 PrePlantingController 处理。
/// 与现有 PlantingService 的 /planting/* 端点完全隔离。
class PrePlantingService {
  final ApiClient _apiClient;

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

  // === 配置与资格 ===

  /// 获取预种功能配置（开关状态）
  ///
  /// 调用 admin-service 的预种配置 API
  Future<PrePlantingConfig> getConfig() async {
    try {
      debugPrint('[PrePlantingService] 获取预种配置');
      final response = await _apiClient.get('/pre-planting/config');

      if (response.statusCode == 200) {
        final data = response.data as Map<String, dynamic>;
        return PrePlantingConfig.fromJson(data);
      }

      throw Exception('获取预种配置失败: ${response.statusCode}');
    } catch (e) {
      debugPrint('[PrePlantingService] 获取预种配置失败: $e');
      rethrow;
    }
  }

  /// 检查购买资格
  ///
  /// 开关开启时任何人可买；关闭时已有未满份额的用户可继续凑满
  Future<PrePlantingEligibility> checkEligibility() async {
    try {
      debugPrint('[PrePlantingService] 检查购买资格');
      final response = await _apiClient.get('/pre-planting/eligibility');

      if (response.statusCode == 200) {
        final data = response.data as Map<String, dynamic>;
        return PrePlantingEligibility.fromJson(data);
      }

      throw Exception('检查购买资格失败: ${response.statusCode}');
    } catch (e) {
      debugPrint('[PrePlantingService] 检查购买资格失败: $e');
      rethrow;
    }
  }

  // === 持仓查询 ===

  /// 获取我的预种持仓信息
  ///
  /// 返回累计份数、待合并份数、已合成树数、省市信息等
  Future<PrePlantingPosition> getMyPosition() async {
    try {
      debugPrint('[PrePlantingService] 获取预种持仓');
      final response = await _apiClient.get('/pre-planting/position');

      if (response.statusCode == 200) {
        final data = response.data as Map<String, dynamic>;
        debugPrint(
          '[PrePlantingService] 持仓: total=${data['totalPortions']}, '
          'available=${data['availablePortions']}, '
          'merged=${data['totalTreesMerged']}',
        );
        return PrePlantingPosition.fromJson(data);
      }

      throw Exception('获取预种持仓失败: ${response.statusCode}');
    } catch (e) {
      debugPrint('[PrePlantingService] 获取预种持仓失败: $e');
      rethrow;
    }
  }

  // === 订单操作 ===

  /// 创建预种订单
  ///
  /// [portionCount] 购买份数（通常为 1）
  /// [provinceCode] 省代码（首次购买时必填，续购自动复用）
  /// [provinceName] 省名称
  /// [cityCode] 市代码
  /// [cityName] 市名称
  ///
  /// 购买流程：创建订单 → 自动扣款 → 分配权益 → 检查合并
  /// 省市信息首次购买时由用户选择，后续购买自动复用。
  Future<CreatePrePlantingOrderResponse> createOrder({
    int portionCount = 1,
    String? provinceCode,
    String? provinceName,
    String? cityCode,
    String? cityName,
  }) async {
    try {
      debugPrint('[PrePlantingService] 创建预种订单: portionCount=$portionCount');

      final Map<String, dynamic> data = {
        'portionCount': portionCount,
      };
      // 首次购买需要提供省市信息
      if (provinceCode != null) data['provinceCode'] = provinceCode;
      if (provinceName != null) data['provinceName'] = provinceName;
      if (cityCode != null) data['cityCode'] = cityCode;
      if (cityName != null) data['cityName'] = cityName;

      final response = await _apiClient.post(
        '/pre-planting/purchase',
        data: data,
      );

      if (response.statusCode == 201 || response.statusCode == 200) {
        final responseData = response.data as Map<String, dynamic>;
        debugPrint('[PrePlantingService] 订单创建成功: ${responseData['orderNo']}');
        return CreatePrePlantingOrderResponse.fromJson(responseData);
      }

      throw Exception('创建预种订单失败: ${response.statusCode}');
    } catch (e) {
      debugPrint('[PrePlantingService] 创建预种订单失败: $e');
      rethrow;
    }
  }

  /// 获取我的预种订单列表
  Future<List<PrePlantingOrder>> getMyOrders({
    int page = 1,
    int pageSize = 20,
  }) async {
    try {
      debugPrint('[PrePlantingService] 获取预种订单列表');
      final response = await _apiClient.get(
        '/pre-planting/orders',
        queryParameters: {'page': page, 'pageSize': pageSize},
      );

      if (response.statusCode == 200) {
        List<dynamic> items;
        if (response.data is List) {
          items = response.data as List<dynamic>;
        } else if (response.data is Map<String, dynamic>) {
          items = (response.data as Map<String, dynamic>)['items'] as List<dynamic>? ?? [];
        } else {
          items = [];
        }
        return items
            .map((e) => PrePlantingOrder.fromJson(e as Map<String, dynamic>))
            .toList();
      }

      throw Exception('获取预种订单列表失败: ${response.statusCode}');
    } catch (e) {
      debugPrint('[PrePlantingService] 获取预种订单列表失败: $e');
      rethrow;
    }
  }

  // === 合并记录 ===

  /// 获取我的合并记录列表（5 份 → 1 棵树）
  Future<List<PrePlantingMerge>> getMyMerges({
    int page = 1,
    int pageSize = 20,
  }) async {
    try {
      debugPrint('[PrePlantingService] 获取合并记录列表');
      final response = await _apiClient.get(
        '/pre-planting/merges',
        queryParameters: {'page': page, 'pageSize': pageSize},
      );

      if (response.statusCode == 200) {
        List<dynamic> items;
        if (response.data is List) {
          items = response.data as List<dynamic>;
        } else if (response.data is Map<String, dynamic>) {
          items = (response.data as Map<String, dynamic>)['items'] as List<dynamic>? ?? [];
        } else {
          items = [];
        }
        return items
            .map((e) => PrePlantingMerge.fromJson(e as Map<String, dynamic>))
            .toList();
      }

      throw Exception('获取合并记录失败: ${response.statusCode}');
    } catch (e) {
      debugPrint('[PrePlantingService] 获取合并记录失败: $e');
      rethrow;
    }
  }

  /// 获取合并详情
  Future<PrePlantingMerge> getMergeDetail(String mergeNo) async {
    try {
      debugPrint('[PrePlantingService] 获取合并详情: mergeNo=$mergeNo');
      final response = await _apiClient.get('/pre-planting/merges/$mergeNo');

      if (response.statusCode == 200) {
        final data = response.data as Map<String, dynamic>;
        return PrePlantingMerge.fromJson(data);
      }

      throw Exception('获取合并详情失败: ${response.statusCode}');
    } catch (e) {
      debugPrint('[PrePlantingService] 获取合并详情失败: $e');
      rethrow;
    }
  }

  /// 下载合并合同预览 PDF
  Future<Uint8List> downloadMergeContractPdf(
    String mergeNo, {
    void Function(int received, int total)? onProgress,
  }) async {
    try {
      debugPrint('[PrePlantingService] 下载合并合同PDF: mergeNo=$mergeNo');
      final response = await _apiClient.get(
        '/pre-planting/merges/$mergeNo/contract-pdf',
        options: Options(
          responseType: ResponseType.bytes,
          receiveTimeout: const Duration(seconds: 120),
        ),
        onReceiveProgress: onProgress,
      );
      if (response.statusCode == 200) {
        debugPrint('[PrePlantingService] PDF下载成功: ${response.data.length} bytes');
        return Uint8List.fromList(response.data as List<int>);
      }
      throw Exception('下载PDF失败: ${response.statusCode}');
    } catch (e) {
      debugPrint('[PrePlantingService] 下载合并合同PDF失败: $e');
      rethrow;
    }
  }

  /// 签署合并合同
  ///
  /// 5 份合并后需要签约，签约后解锁交易/提现/授权限制
  Future<void> signMergeContract(String mergeNo) async {
    try {
      debugPrint('[PrePlantingService] 签署合并合同: mergeNo=$mergeNo');
      final response = await _apiClient.post(
        '/pre-planting/sign-contract',
        data: {'mergeNo': mergeNo},
      );

      if (response.statusCode == 200) {
        debugPrint('[PrePlantingService] 合同签署成功');
        return;
      }

      throw Exception('签署合同失败: ${response.statusCode}');
    } catch (e) {
      debugPrint('[PrePlantingService] 签署合同失败: $e');
      rethrow;
    }
  }

  /// 获取"我收到的"预种奖励
  ///
  /// 返回 { summary: { settleableUsdt }, settleableRewards: [...] }
  Future<PrePlantingMyRewards> getMyRewards() async {
    try {
      debugPrint('[PrePlantingService] 获取我的预种奖励');
      final response = await _apiClient.get('/pre-planting/my-rewards');

      if (response.statusCode == 200) {
        final data = response.data as Map<String, dynamic>;
        return PrePlantingMyRewards.fromJson(data);
      }

      debugPrint('[PrePlantingService] 获取预种奖励失败: ${response.statusCode}');
      return PrePlantingMyRewards.empty();
    } catch (e) {
      debugPrint('[PrePlantingService] 获取预种奖励异常: $e');
      return PrePlantingMyRewards.empty();
    }
  }
}

/// 预种奖励返回数据
class PrePlantingMyRewards {
  final double settleableUsdt;
  final List<PrePlantingRewardItem> settleableRewards;

  PrePlantingMyRewards({
    required this.settleableUsdt,
    required this.settleableRewards,
  });

  factory PrePlantingMyRewards.empty() => PrePlantingMyRewards(
    settleableUsdt: 0,
    settleableRewards: [],
  );

  factory PrePlantingMyRewards.fromJson(Map<String, dynamic> json) {
    final summary = json['summary'] as Map<String, dynamic>? ?? {};
    final rewards = json['settleableRewards'] as List<dynamic>? ?? [];

    return PrePlantingMyRewards(
      settleableUsdt: (summary['settleableUsdt'] ?? 0).toDouble(),
      settleableRewards: rewards
          .map((r) => PrePlantingRewardItem.fromJson(r as Map<String, dynamic>))
          .toList(),
    );
  }
}

/// 预种奖励条目
class PrePlantingRewardItem {
  final String id;
  final String rightType;
  final double usdtAmount;
  final double hashpowerAmount;
  final DateTime createdAt;
  final String sourceOrderNo;
  final String? sourceAccountSequence;
  final String memo;

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

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