import 'package:dio/dio.dart';

typedef PageResult = ({List<Map<String, dynamic>> items, bool hasMore});

// type: 0=市价，1=限价，2=计划委托
// direction: 0=做多，1=做空
// 撤单传 entrustId（数字 ID）
class FuturesService {
  const FuturesService(this._dio);

  final Dio _dio;

  static final _form = Options(
    contentType: 'application/x-www-form-urlencoded',
  );

  // ── 合约信息 ─────────────────────────────────────────────────

  Future<Map<String, dynamic>> getSymbolInfo(String symbol) async {
    final resp = await _dio.post<Map<String, dynamic>>(
      'swap/symbol-info',
      data: {'symbol': symbol},
      options: _form,
    );
    final data = resp.data?['data'];
    if (data is Map<String, dynamic>) return data;
    return resp.data ?? {};
  }

  // ── 杠杆 ─────────────────────────────────────────────────────

  Future<int> getLeverage(int contractId) async {
    final resp = await _dio.post<Map<String, dynamic>>(
      'swap/wallet-new/getLeverage',
      data: {'contractId': contractId},
      options: _form,
    );
    final data = resp.data?['data'];
    return (data is num ? data.toInt() : int.tryParse('$data')) ?? 20;
  }

  Future<void> modifyLeverage(int contractId, int leverage) async {
    await _dio.post<dynamic>(
      'swap/wallet-new/modifyLeverage',
      data: {'contractId': contractId, 'leverage': leverage},
      options: _form,
    );
  }

  /// 切换仓位模式：0=合仓（全仓）1=分仓
  /// 后端要求有持仓/委托时禁止切换，失败会抛异常
  Future<void> modifyPositionType(int positionType) async {
    await _dio.post<dynamic>(
      'swap/wallet-new/modifyType',
      data: {'positionType': positionType},
      options: _form,
    );
  }

  // ── 账户与仓位 ───────────────────────────────────────────────

  Future<Map<String, dynamic>> getWithPositions([String symbol = '']) async {
    final resp = await _dio.get<Map<String, dynamic>>(
      'swap/wallet-new/get-with-positions',
      queryParameters: symbol.isNotEmpty ? {'symbol': symbol} : null,
    );
    return (resp.data?['data'] as Map<String, dynamic>?) ?? {};
  }

  // ── 委托单 ───────────────────────────────────────────────────

  Future<PageResult> getCurrentOrders({
    int pageNo = 1,
    int pageSize = 10,
  }) async {
    final resp = await _dio.get<Map<String, dynamic>>(
      'swap/order/current',
      queryParameters: {'pageNo': pageNo, 'pageSize': pageSize},
    );
    return _extractPage(resp.data, pageSize);
  }

  static PageResult _extractPage(Map<String, dynamic>? body, int pageSize) {
    if (body == null) return (items: [], hasMore: false);

    List<Map<String, dynamic>> items = [];

    final direct = body['content'] ?? body['records'] ?? body['list'];
    if (direct is List) {
      items = direct.map((e) => Map<String, dynamic>.from(e as Map)).toList();
      final last = body['last'];
      final hasMore = last is bool ? !last : items.length >= pageSize;
      return (items: items, hasMore: hasMore);
    }

    final nested = body['data'];
    if (nested is Map) {
      final content = nested['content'] ?? nested['records'] ?? nested['list'];
      if (content is List) {
        items = content.map((e) => Map<String, dynamic>.from(e as Map)).toList();
        final last = nested['last'];
        final hasMore = last is bool ? !last : items.length >= pageSize;
        return (items: items, hasMore: hasMore);
      }
    }
    if (nested is List) {
      items = nested.map((e) => Map<String, dynamic>.from(e as Map)).toList();
      return (items: items, hasMore: items.length >= pageSize);
    }
    return (items: [], hasMore: false);
  }

  // ── 开仓 ─────────────────────────────────────────────────────

  Future<void> openOrder({
    required int contractCoinId,
    required int type,
    required int direction,
    required double volume,
    required int leverage,
    double? entrustPrice,
    double? triggerPrice,
    double? profitPrice,
    double? lossPrice,
    int? isPercentage, // 1=百分比模式
    int? positionType, // 0=全仓 1=分仓，由前端传递
  }) async {
    // 计划委托无 entrustPrice 时传 0（市价）
    final effectiveEntrustPrice = (type == 2 && (entrustPrice == null || entrustPrice <= 0))
        ? 0.0
        : entrustPrice;

    await _dio.post<dynamic>(
      'swap/order/open/v3',
      data: {
        'contractCoinId': contractCoinId,
        'type': type,
        'direction': direction,
        'volume': volume.toString(),
        'leverage': leverage,
        'entrustPrice': effectiveEntrustPrice?.toString() ?? '',
        'triggerPrice': triggerPrice?.toString() ?? '',
        'profitPrice': profitPrice?.toString() ?? '',
        'lossPrice': lossPrice?.toString() ?? '',
        if (isPercentage != null) 'isPercentage': isPercentage,
        if (positionType != null) 'positionType': positionType,
      },
      options: _form,
    );
  }

  // ── 平仓 ─────────────────────────────────────────────────────

  Future<void> closeMarket({
    required String positionId,
    required double volume,
  }) async {
    await _dio.post<dynamic>(
      'swap/order/close',
      data: {
        'positionId': positionId,
        'volume': volume.toString(),
        'type': 0,
        'entrustPrice': '0',
        'triggerPrice': '0',
      },
      options: _form,
    );
  }

  Future<void> closeLimit({
    required String positionId,
    required double price,
    required double volume,
  }) async {
    await _dio.post<dynamic>(
      'swap/order/close',
      data: {
        'positionId': positionId,
        'entrustPrice': price.toString(),
        'volume': volume.toString(),
        'type': 1,
        'triggerPrice': '0',
      },
      options: _form,
    );
  }

  Future<void> closeAllPositions() async {
    await _dio.post<dynamic>('swap/order/close-all-coins', options: _form);
  }

  // entrustPrice=0 → 计划市价；>0 → 计划限价
  Future<void> closeConditional({
    required String positionId,
    required double triggerPrice,
    required double volume,
    double entrustPrice = 0,
  }) async {
    await _dio.post<dynamic>(
      'swap/order/close',
      data: {
        'positionId': positionId,
        'entrustPrice': entrustPrice.toString(),
        'volume': volume.toString(),
        'type': 2,
        'triggerPrice': triggerPrice.toString(),
      },
      options: _form,
    );
  }

  Future<void> reverseOpenPosition(String positionId) async {
    await _dio.post<dynamic>(
      'swap/order/close-and-open',
      data: {'positionId': positionId},
      options: _form,
    );
  }

  // ── 撤单 ─────────────────────────────────────────────────────

  Future<void> cancelOrder(int entrustId) async {
    await _dio.post<dynamic>(
      'swap/order/cancel',
      data: {'entrustId': entrustId},
      options: _form,
    );
  }

  // entrustIds 以 JSON 数组字符串传递，如 "[1,2,3]"
  Future<void> cancelOrdersByIds(List<int> entrustIds) async {
    await _dio.post<dynamic>(
      'swap/order/cancel-by-ids',
      data: {'entrustIds': entrustIds.toString()},
      options: _form,
    );
  }

  // ── 止盈止损 ─────────────────────────────────────────────────

  // 首次设置（无 cutEntrustId）
  Future<void> setTpsl({
    required String positionId,
    double? profitPrice,
    double? lossPrice,
  }) async {
    await _dio.post<dynamic>(
      'swap/order/cut-position',
      data: {
        'positionId': positionId,
        'profitPrice': profitPrice?.toString() ?? '0',
        'profitEntrustPrice': '0.0',
        'lossPrice': lossPrice?.toString() ?? '0',
        'lossEntrustPrice': '0.0',
      },
      options: _form,
    );
  }

  // 修改已有止盈止损委托（有 cutEntrustId）
  Future<void> modifyCutOrder({
    required int entrustId,
    double? profitPrice,
    double? lossPrice,
  }) async {
    await _dio.post<dynamic>(
      'swap/order/modify-cut',
      data: {
        'entrustId': entrustId,
        'profitPrice': profitPrice?.toString() ?? '0',
        'lossPrice': lossPrice?.toString() ?? '0',
      },
      options: _form,
    );
  }

  // ── 历史记录 ─────────────────────────────────────────────────

  Future<PageResult> getPositionHistory({
    int pageNo = 1,
    int pageSize = 10,
  }) async {
    final resp = await _dio.get<Map<String, dynamic>>(
      'swap/position/history',
      queryParameters: {'pageNo': pageNo, 'pageSize': pageSize},
    );
    return _extractPage(resp.data, pageSize);
  }

  Future<PageResult> getOrderHistoryAll({
    int pageNo = 1,
    int pageSize = 10,
  }) async {
    final resp = await _dio.get<Map<String, dynamic>>(
      'swap/order/history-all',
      queryParameters: {'pageNo': pageNo, 'pageSize': pageSize},
    );
    return _extractPage(resp.data, pageSize);
  }

}
