import 'dart:collection';

import 'package:dio/dio.dart';
import 'package:news_getx/config/cache.dart';

class CacheObject {
  Response response;
  int timestamp;

  CacheObject(this.response)
      : timestamp = DateTime.now().millisecondsSinceEpoch;

  @override
  bool operator ==(Object other) {
    return response.hashCode == other.hashCode;
  }

  @override
  int get hashCode => response.realUri.hashCode;
}

class NetCache extends Interceptor {
  // 为确保迭代器顺序和对象插入时间一致顺序一致，我们使用LinkedHashMap, 默认的字面量{}就是有序的
  // 内存缓存
  var cache = <String, CacheObject>{};

  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    // refresh标记是否是"下拉刷新"
    bool refresh = options.extra['refresh'] == true;
    if (refresh) {
      // 如果是下拉刷新，先删除相关缓存
      if (options.extra['list']) {
        //若是列表，则只要url中包含当前path的缓存全部删除（简单实现，并不精准）
        cache.removeWhere((key, value) => key.contains(options.path));
      } else {
        cacheDelete(options.uri.toString());
      }
    }

    // get 请求，开启缓存
    if (options.extra['noCache'] != true &&
        options.method.toLowerCase() == "get") {
      String key = options.extra['cacheKey'] ?? options.uri.toString();
      var ob = cache[key];

      if (ob != null) {
        //若缓存未过期，则返回缓存内容
        if ((DateTime.now().millisecondsSinceEpoch - ob.timestamp) / 1000 <
            CacheMaxAge) {
          CacheObject? cacheRes = cache[key];
          if (cacheRes != null) {
            handler.resolve(cacheRes.response);
            return;
          }
        } else {
          //若已过期则删除缓存，继续向服务器请求
          cacheDelete(key);
        }
      }
    }

    super.onRequest(options, handler);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    // 将返回结果保存到缓存
    _setCache(response);
    super.onResponse(response, handler);
  }

  _setCache(Response response) {
    RequestOptions options = response.requestOptions;
    // 只缓存 get 的请求
    if (options.extra["noCache"] != true &&
        options.method.toLowerCase() == "get") {
      // 如果缓存数量超过最大数量限制，则先移除最早的一条记录
      if (cache.length >= CacheMaxCount) {
        cacheDelete(cache.keys.first);
      }

      String key = options.extra['cacheKey'] ?? options.uri.toString();
      cache[key] = CacheObject(response);
    }
  }

  void cacheDelete(String key) {
    cache.remove(key);
  }
}
