/*
 * @Author: XianKaiQun
 * @Date: 2020-04-21 10:09:01
 * @LastEditors: wuwei
 * @LastEditTime: 2023-12-01 15:48:32
 * @Descripttion:
 */

import 'dart:convert';
import 'package:app_package/app_package.dart';
import 'package:dio/io.dart';
import 'package:flutter/cupertino.dart';
import 'package:wisdom_cli/wisdom_cli.dart';
import 'package:dio/dio.dart'; // TOD:因dio依赖库与flutter自带http库 有类命名冲突

///请求器单例
class HttpUtil with DioMixin implements Dio {
  HttpUtil();
  HttpUtil._();
  static late HttpUtil _instance;
  static HttpUtil get instance {
    _instance = HttpUtil._();
    return _instance;
  }

  @override
  BaseOptions options = BaseOptions(
    baseUrl: APPConfig.baseURL,
    sendTimeout: Duration(seconds: 5,),
    contentType: 'application/json',
    validateStatus: (e) => true, //关闭code!=200时的报错
  );

  @override
  HttpClientAdapter httpClientAdapter = DefaultHttpClientAdapter();

  @override
  get interceptors => Interceptors()
    ..addAll(
      [
        LoginInterceptors(), //登录拦截器
        StatusInterceptors(), //状态拦截器
      ],
    );
}

///Cookie管理
class CookieUtil {
  CookieUtil._();
  static late CookieUtil _instance;
  static CookieUtil get instance {
    _instance = CookieUtil._();
    return _instance;
  }

  final _key = 'storage-cookie';

  String? get value => WisStorageUtil.get(key: _key);

  Future<bool> set(String str) async {
    return await WisStorageUtil.set(key: _key, data: str);
  }

  Future<bool> remove() async => await WisStorageUtil.remove(key: _key);
}

///账号密码保存
class LoginInfoUtil {
  LoginInfoUtil._();
  static late LoginInfoUtil _instance;
  static LoginInfoUtil get instance {
    _instance = LoginInfoUtil._();
    return _instance;
  }

  final _key = 'storage-loginInfo';

  Map get value => WisStorageUtil.get(key: _key) ?? {};

  Future<bool> set(String str) async {
    return await WisStorageUtil.set(key: _key, data: str);
  }

  Future<bool> remove() async => await WisStorageUtil.remove(key: _key);
}

///登录拦截器
///
///保存帐号密码企业号
///
///401拦截跳转登录页
///
///保存cookie 设置cookie
class LoginInterceptors extends InterceptorsWrapper {
  ///请求前
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    ///赋值cookie
    final cookie = CookieUtil.instance.value;
    options.headers['Cookie'] = cookie;

    ///接口没传entCode 可判断为非login，加上企业号
    if (options.headers['entcode'] == null ||
        options.headers['entcode'] == '') {
      Map loginInfo = LoginInfoUtil.instance.value;
      options.headers['entcode'] = loginInfo['entCode'] ?? '';
    }

    return super.onRequest(options, handler);
  }

  ///响应后
  @override
  Future onResponse(
      Response response, ResponseInterceptorHandler handler) async {
    ///储存cookie
    final code = response.statusCode;
    if (code! < 300) {
      ///从cookie数组中取到有用的那个cookie
      final cookies =
          response.headers.map['set-cookie']?.join(';').split(';') ?? [];
      if (cookies.length != 0) {
        await CookieUtil.instance.set(cookies[0]);
      }
    } else if (code == 401) {
      /// TODO:
      await GetIt.I.get<AuthGlobalStore>().logout();
      HttpUtil.instance.close();
    }
    return super.onResponse(response, handler);
  }
}

///状态码拦截器
///
///打印错误消息
///
///显示错误吐司提示
///
///给发送钉钉错误通知
class StatusInterceptors extends InterceptorsWrapper {
  late RequestOptions requestOptions;

  ///请求前
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    requestOptions = options;
    debugPrint("[${options.method}] => ${options.path}");
    debugPrint("[${options.headers}]");
    if (options.queryParameters.keys.length != 0) {
      String jsonParams = jsonEncode(options.queryParameters);
      debugPrint("query => $jsonParams");
    }
    if (options.data != null) {
      if (options.data is FormData) {
        debugPrint("data => ${options.data}");
      } else {
        String jsonData = jsonEncode(options.data ?? {});
        debugPrint("data => $jsonData");
      }
    }
    return super.onRequest(options, handler);
  }

  ///响应后
  @override
  Future onResponse(
      Response response, ResponseInterceptorHandler handler) async {
    final code = response.statusCode;
    final options = response.requestOptions;

    ///401在登录拦截器中拦截
    ///403无权限在模块内自处理
    if (code! > 300 && code != 401 && code != 403) {
      try {
        WToastUtil.show(response.data['responseJSON']['message']);
        WLoadingUtil.hide();
      } catch (e) {
        WToastUtil.show('ErrorCode:$code');
        WLoadingUtil.hide();
      }
      // final responseData = response;



      /// 发布环境:发送钉钉 去除报警接口报错的再次调起（2024.10.21）
      // if (APPConfig.isRelease && options.path != "/risk/ding/front/chat/send") {
      //   CatchErrorUtil.post(
      //     api: '[${options.method}]=>${options.baseUrl}${options.path}',
      //     title: '$code',
      //     route: '${Get.currentRoute}',
      //     params: '${options.data}',
      //     response: '$responseData',
      //     entCode: '${options.headers['entcode']}',
      //   );
      // }
      debugPrint('$options');
      debugPrint(
          "---------------------------------------------------------------------NetWork-Error(网络错误)----------------------------------");
      debugPrint("[$code] => ${options.path}");
      /// 打印传参用的应该是data属性，而不是queryParameters
      debugPrint("[$code] => ${options.data}");
    }

    return super.onResponse(response, handler);
  }

  ///请求失败
  @override
  void onError(DioError err, ErrorInterceptorHandler handler) {
    // if (err?.error != null) {
    //   print(err?.error);
    //   debugPrint(
    //       "ERROR[${err?.response?.statusCode}] => ${err?.error is String ? err?.error : err?.error?.path ?? ''}");
    // }
    return super.onError(err, handler);
  }
}
