import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../domain/entities/contribution.dart';
import '../../domain/entities/contribution_record.dart';
import '../../domain/entities/contribution_stats.dart';
import '../../domain/usecases/contribution/get_user_contribution.dart';
import '../../domain/repositories/contribution_repository.dart';
import '../../core/di/injection.dart';
import '../../core/network/api_client.dart';
import '../../core/network/api_endpoints.dart';
import 'mining_providers.dart';

final getUserContributionUseCaseProvider = Provider<GetUserContribution>((ref) {
  return getIt<GetUserContribution>();
});

final contributionRepositoryProvider = Provider<ContributionRepository>((ref) {
  return getIt<ContributionRepository>();
});

final contributionProvider = FutureProvider.family<Contribution?, String>(
  (ref, accountSequence) async {
    // 空字符串不请求
    if (accountSequence.isEmpty) return null;

    final useCase = ref.watch(getUserContributionUseCaseProvider);
    final result = await useCase(accountSequence);

    // 保持 provider 活跃，避免重复请求
    ref.keepAlive();

    // 5 分钟后自动失效
    final timer = Timer(const Duration(minutes: 5), () {
      ref.invalidateSelf();
    });
    ref.onDispose(() => timer.cancel());

    return result.fold(
      (failure) => throw Exception(failure.message),
      (contribution) => contribution,
    );
  },
);

/// 贡献值记录请求参数
class ContributionRecordsParams {
  final String accountSequence;
  final int page;
  final int pageSize;
  final ContributionSourceType? sourceType;

  const ContributionRecordsParams({
    required this.accountSequence,
    this.page = 1,
    this.pageSize = 10,
    this.sourceType,
  });

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is ContributionRecordsParams &&
          runtimeType == other.runtimeType &&
          accountSequence == other.accountSequence &&
          page == other.page &&
          pageSize == other.pageSize &&
          sourceType == other.sourceType;

  @override
  int get hashCode => accountSequence.hashCode ^ page.hashCode ^ pageSize.hashCode ^ sourceType.hashCode;
}

/// 贡献值记录 Provider
final contributionRecordsProvider = FutureProvider.family<ContributionRecordsPage?, ContributionRecordsParams>(
  (ref, params) async {
    // 空字符串不请求
    if (params.accountSequence.isEmpty) {
      return null;
    }

    final repository = ref.watch(contributionRepositoryProvider);
    final result = await repository.getContributionRecords(
      params.accountSequence,
      sourceType: params.sourceType,
      page: params.page,
      pageSize: params.pageSize,
    );

    // 保持 provider 活跃
    ref.keepAlive();

    // 5 分钟后自动失效
    final timer = Timer(const Duration(minutes: 5), () {
      ref.invalidateSelf();
    });
    ref.onDispose(() => timer.cancel());

    return result.fold(
      (failure) => throw Exception(failure.message),
      (records) => records,
    );
  },
);

/// 全网贡献值统计 Provider
final contributionStatsProvider = FutureProvider<ContributionStats?>((ref) async {
  final repository = ref.watch(contributionRepositoryProvider);
  final result = await repository.getContributionStats();

  // 保持 provider 活跃
  ref.keepAlive();

  // 5 分钟后自动失效
  final timer = Timer(const Duration(minutes: 5), () {
    ref.invalidateSelf();
  });
  ref.onDispose(() => timer.cancel());

  return result.fold(
    (failure) => null,
    (stats) => stats,
  );
});

/// 计算用户今日预估收益
/// 公式: 用户每秒收益 × 60分钟 × 60秒 × 24小时
class EstimatedEarnings {
  final String dailyShares;
  final String perSecondShares;
  final bool isValid;

  const EstimatedEarnings({
    required this.dailyShares,
    required this.perSecondShares,
    required this.isValid,
  });

  static const zero = EstimatedEarnings(
    dailyShares: '0',
    perSecondShares: '0',
    isValid: false,
  );
}

final estimatedEarningsProvider = Provider.family<EstimatedEarnings, String>((ref, accountSequence) {
  // 从 mining-service 获取用户每秒收益
  final shareAccountAsync = ref.watch(shareAccountProvider(accountSequence));
  final shareAccount = shareAccountAsync.valueOrNull;

  if (shareAccount == null) {
    return EstimatedEarnings.zero;
  }

  final perSecondEarning = double.tryParse(shareAccount.perSecondEarning) ?? 0;

  if (perSecondEarning <= 0) {
    return EstimatedEarnings.zero;
  }

  // 每日预估 = 每秒收益 × 86400（60×60×24）
  final dailyShares = perSecondEarning * 86400;

  return EstimatedEarnings(
    dailyShares: dailyShares.toStringAsFixed(4),
    perSecondShares: perSecondEarning.toStringAsFixed(8),
    isValid: true,
  );
});

/// 控制是否隐藏金额显示的状态
final hideAmountsProvider = StateProvider<bool>((ref) => false);

/// 积分股池余量数据类
class SharePoolBalance {
  final String poolA;
  final String poolB;
  final String total;

  const SharePoolBalance({
    required this.poolA,
    required this.poolB,
    required this.total,
  });

  factory SharePoolBalance.fromJson(Map<String, dynamic> json) {
    return SharePoolBalance(
      poolA: json['poolA'] ?? '0',
      poolB: json['poolB'] ?? '0',
      total: json['total'] ?? '0',
    );
  }

  static const zero = SharePoolBalance(poolA: '0', poolB: '0', total: '0');
}

/// 积分股池总余量 Provider
final sharePoolBalanceProvider = FutureProvider<SharePoolBalance>((ref) async {
  final client = getIt<ApiClient>();

  try {
    final response = await client.get(ApiEndpoints.sharePoolBalance);
    return SharePoolBalance.fromJson(response.data as Map<String, dynamic>);
  } catch (e) {
    return SharePoolBalance.zero;
  }
});
