import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../data/models/copy_trading/copy_account.dart';
import '../data/models/copy_trading/copy_position.dart';
import '../data/models/copy_trading/trader.dart';
import '../data/repositories/copy_trading_repository.dart';
import 'auth_provider.dart';

// ── UI State ─────────────────────────────────────────────

class MyCopyTradingState {
  final CopyAccount? account;
  final List<CopyPosition> currentPositions;
  final List<CopyPosition> historyPositions;
  final List<Trader> myTraders;
  final bool isLoading;
  final int tabIndex; // 0=当前跟单 1=我的交易员 2=历史跟单

  // ── 分页状态（每个 tab 独立） ─────────────────────────
  final int currentPage;
  final bool currentHasMore;
  final bool currentLoadingMore;

  final int tradersPage;
  final bool tradersHasMore;
  final bool tradersLoadingMore;

  final int historyPage;
  final bool historyHasMore;
  final bool historyLoadingMore;

  const MyCopyTradingState({
    this.account,
    this.currentPositions = const [],
    this.historyPositions = const [],
    this.myTraders = const [],
    this.isLoading = false,
    this.tabIndex = 0,
    this.currentPage = 1,
    this.currentHasMore = true,
    this.currentLoadingMore = false,
    this.tradersPage = 1,
    this.tradersHasMore = true,
    this.tradersLoadingMore = false,
    this.historyPage = 1,
    this.historyHasMore = true,
    this.historyLoadingMore = false,
  });

  MyCopyTradingState copyWith({
    CopyAccount? account,
    List<CopyPosition>? currentPositions,
    List<CopyPosition>? historyPositions,
    List<Trader>? myTraders,
    bool? isLoading,
    int? tabIndex,
    int? currentPage,
    bool? currentHasMore,
    bool? currentLoadingMore,
    int? tradersPage,
    bool? tradersHasMore,
    bool? tradersLoadingMore,
    int? historyPage,
    bool? historyHasMore,
    bool? historyLoadingMore,
  }) =>
      MyCopyTradingState(
        account: account ?? this.account,
        currentPositions: currentPositions ?? this.currentPositions,
        historyPositions: historyPositions ?? this.historyPositions,
        myTraders: myTraders ?? this.myTraders,
        isLoading: isLoading ?? this.isLoading,
        tabIndex: tabIndex ?? this.tabIndex,
        currentPage: currentPage ?? this.currentPage,
        currentHasMore: currentHasMore ?? this.currentHasMore,
        currentLoadingMore: currentLoadingMore ?? this.currentLoadingMore,
        tradersPage: tradersPage ?? this.tradersPage,
        tradersHasMore: tradersHasMore ?? this.tradersHasMore,
        tradersLoadingMore: tradersLoadingMore ?? this.tradersLoadingMore,
        historyPage: historyPage ?? this.historyPage,
        historyHasMore: historyHasMore ?? this.historyHasMore,
        historyLoadingMore: historyLoadingMore ?? this.historyLoadingMore,
      );
}

// ── Notifier ─────────────────────────────────────────────

class MyCopyTradingNotifier extends Notifier<MyCopyTradingState> {
  static const _pageSize = 10;

  @override
  MyCopyTradingState build() {
    final isLoggedIn = ref.watch(isLoggedInProvider);
    if (isLoggedIn) Future.microtask(_load);
    return const MyCopyTradingState(isLoading: true);
  }

  CopyTradingRepository get _repo => ref.read(copyTradingRepositoryProvider);

  Future<void> _load({bool silent = false}) async {
    if (!silent) state = state.copyWith(isLoading: true);
    try {
      // 并行加载全部数据（第1页，每页10条）
      final results = await Future.wait([
        _repo.getFollowWallet(),
        _repo.getCurrentCopyPositions(page: 1, pageSize: _pageSize),
        _repo.getFollowingTraders(page: 1, pageSize: _pageSize),
        _repo.getHistoryCopyPositions(page: 1, pageSize: _pageSize),
      ]);

      final walletMap = results[0] as Map<String, dynamic>?;
      final currentMaps = results[1] as List<Map<String, dynamic>>;
      final traderMaps = results[2] as List<Map<String, dynamic>>;
      final historyMaps = results[3] as List<Map<String, dynamic>>;

      // 未实现盈亏 = 当前所有持仓的 profit 之和
      // （follow-wallet/get 的 currentRevenue 字段服务端返回 0，需客户端汇总）
      final totalUnrealizedPnl = currentMaps.fold<double>(
        0.0,
        (sum, m) => sum + (double.tryParse((m['profit'] ?? '0').toString()) ?? 0.0),
      );
      CopyAccount? account;
      if (walletMap != null) {
        account = CopyAccount.fromApi(walletMap).copyWith(unrealizedPnl: totalUnrealizedPnl);
      }

      state = state.copyWith(
        isLoading: false,
        account: account,
        currentPositions: currentMaps.map(CopyPosition.fromApi).toList(),
        myTraders: traderMaps.map((e) => Trader.fromApi(e)).toList(),
        historyPositions: historyMaps.map(CopyPosition.fromApi).toList(),
        currentPage: 1,
        currentHasMore: currentMaps.length >= _pageSize,
        currentLoadingMore: false,
        tradersPage: 1,
        tradersHasMore: traderMaps.length >= _pageSize,
        tradersLoadingMore: false,
        historyPage: 1,
        historyHasMore: historyMaps.length >= _pageSize,
        historyLoadingMore: false,
      );
    } catch (e) {
      state = state.copyWith(isLoading: false);
    }
  }

  void setTab(int index) {
    state = state.copyWith(tabIndex: index);
    Future.microtask(silentRefresh);
  }

  /// 首次加载（显示全屏 spinner）
  Future<void> refresh() => _load();

  /// 静默刷新，不显示全屏 spinner（用于下拉刷新、tab 切换）
  Future<void> silentRefresh() => _load(silent: true);

  Future<void> loadMoreCurrent() async {
    if (!state.currentHasMore || state.currentLoadingMore || state.isLoading) return;
    final nextPage = state.currentPage + 1;
    state = state.copyWith(currentLoadingMore: true);
    try {
      final maps = await _repo.getCurrentCopyPositions(page: nextPage, pageSize: _pageSize);
      state = state.copyWith(
        currentLoadingMore: false,
        currentPositions: [...state.currentPositions, ...maps.map(CopyPosition.fromApi)],
        currentPage: nextPage,
        currentHasMore: maps.length >= _pageSize,
      );
    } catch (_) {
      state = state.copyWith(currentLoadingMore: false);
    }
  }

  Future<void> loadMoreTraders() async {
    if (!state.tradersHasMore || state.tradersLoadingMore || state.isLoading) return;
    final nextPage = state.tradersPage + 1;
    state = state.copyWith(tradersLoadingMore: true);
    try {
      final maps = await _repo.getFollowingTraders(page: nextPage, pageSize: _pageSize);
      state = state.copyWith(
        tradersLoadingMore: false,
        myTraders: [...state.myTraders, ...maps.map((e) => Trader.fromApi(e))],
        tradersPage: nextPage,
        tradersHasMore: maps.length >= _pageSize,
      );
    } catch (_) {
      state = state.copyWith(tradersLoadingMore: false);
    }
  }

  Future<void> loadMoreHistory() async {
    if (!state.historyHasMore || state.historyLoadingMore || state.isLoading) return;
    final nextPage = state.historyPage + 1;
    state = state.copyWith(historyLoadingMore: true);
    try {
      final maps = await _repo.getHistoryCopyPositions(page: nextPage, pageSize: _pageSize);
      state = state.copyWith(
        historyLoadingMore: false,
        historyPositions: [...state.historyPositions, ...maps.map(CopyPosition.fromApi)],
        historyPage: nextPage,
        historyHasMore: maps.length >= _pageSize,
      );
    } catch (_) {
      state = state.copyWith(historyLoadingMore: false);
    }
  }

  Future<void> unfollowTrader(String traderId) async {
    await _repo.unfollowTrader(traderId);
    await _load();
  }

  Future<void> closePosition(String positionId) async {
    // 乐观更新：立即从列表移除，让用户感知即时响应
    final original = state.currentPositions;
    state = state.copyWith(
      currentPositions: original.where((p) => p.id != positionId).toList(),
    );
    try {
      await _repo.closeCopyPosition(positionId);
      // 静默刷新当前持仓列表（不影响其他 tab 数据、不显示全屏 loading）
      await _refreshCurrentPositions();
    } catch (e) {
      // API 失败则还原列表
      state = state.copyWith(currentPositions: original);
      rethrow;
    }
  }

  Future<void> _refreshCurrentPositions() async {
    try {
      final maps = await _repo.getCurrentCopyPositions(page: 1, pageSize: _pageSize);
      final totalUnrealizedPnl = maps.fold<double>(
        0.0,
        (sum, m) => sum + (double.tryParse((m['profit'] ?? '0').toString()) ?? 0.0),
      );
      final account = state.account?.copyWith(unrealizedPnl: totalUnrealizedPnl);
      state = state.copyWith(
        currentPositions: maps.map(CopyPosition.fromApi).toList(),
        account: account ?? state.account,
        currentPage: 1,
        currentHasMore: maps.length >= _pageSize,
        currentLoadingMore: false,
      );
    } catch (_) {}
  }
}

final myCopyTradingProvider =
    NotifierProvider<MyCopyTradingNotifier, MyCopyTradingState>(
  MyCopyTradingNotifier.new,
);
