import 'dart:async';

import 'package:fis_common/http/http.dart';
import 'package:fis_common/http/options.dart';
import 'package:dio/dio.dart' as dio;

class _JsonRpcHttpPool {
  _JsonRpcHttpPool({int limitCount = 2}) {
    _limitCount = limitCount;
  }

  static const _TimerInterval = 60 * 1000;
  static const _LifecycleTime = 60 * 1000;

  Timer? _timer;
  final Map<int, _ClientState> _pool = {};
  late int _limitCount;
  int get limitCount => _limitCount;
  bool _closed = false;
  bool _firstCall = true;

  void _handleFirstLoad() {
    if (!_firstCall) return;
    _timer =
        Timer.periodic(const Duration(milliseconds: _TimerInterval), (timer) {
      final now = DateTime.now();
      _pool.forEach((key, value) {
        var secDiff = now.difference(value.lastVisitTime).inSeconds;
        if (_LifecycleTime < secDiff) {
          _pool.remove(key);
        }
      });
    });

    _firstCall = false;
  }

  void close() {
    if (!_closed) {
      _closed = true;
      _timer?.cancel();
    }
  }

  /// 设置连接池缓存数
  void setLimitCount(int count) => _limitCount = count;

  /// 获取客户端实例
  FHttp getClient(
    String baseUrl, {
    int? timeout,
    Map<String, dynamic>? headers,
  }) {
    if (!_pool.containsKey(baseUrl.hashCode)) {
      // 浏览器跨域限制: Content-Type非简单类型 Fetch前会先发一个Options,Server不支持Options导致Cors
      // 简单类型:
      //  - application/x-www-form-urlencoded
      //  - multipart/form-data
      //  - text/plain
      final _client = FHttp(FHttpBaseOptions(
        baseUrl: baseUrl,
        timeout: timeout ?? 15 * 1000,
        headers: headers,
        contentType: dio.Headers.textPlainContentType,
        responseType: FHttpResponseType.json,
      ));

      final _state = _ClientState(_client);
      _pool[baseUrl.hashCode] = _state;
      if (_pool.length > limitCount) {
        _pool.remove(_pool.keys.first); // 删除第一个
      }
    }
    final state = _pool[baseUrl.hashCode]!;
    state.lastVisitTime = DateTime.now();
    _handleFirstLoad();
    return state.client;
  }
}

class _ClientState {
  _ClientState(this.client);
  final FHttp client;
  DateTime lastVisitTime = DateTime.now();
}

final _JsonRpcHttpPool jrpcHttpPool = _JsonRpcHttpPool();