import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import 'package:amos_flutter_api/amos_flutter_api.dart' hide Logger;
import 'package:amos_iot_login_tpl/amos_iot_login_tpl.dart';
import 'package:dio/dio.dart';
import 'package:get/get.dart' hide Response;
import 'package:jcs_airport/consts/Logger.dart';

import '../consts/http_config.dart';
import './cache_utils.dart';

///平台http客户端
class AmosHttp {
  static final HttpManager amosHttp = HttpManager(HttpConfig.GateWayURL,
      connectTimeout: HttpConfig.connTimeout, receiveTimeout: HttpConfig.recTimeout, interceptor: Http.logInterceptor);
  static Http client = Http(amosHttp);
}

///contentType
enum ContentType { JSON, FORM_URL_ENCODED, MULTIPART_FORM_DATA }

///method
enum _Method { GET, POST, PUT }

class Http {
  HttpManager httpManager;

  Http(this.httpManager);

  ///日志拦截器
  static Interceptor logInterceptor = InterceptorsWrapper(onRequest: (options) {
    Logger.info('================ 请求数据开始 ================');
    Logger.info('method = ${options.method.toString()}');
    Logger.info('url = ${options.uri.toString()}');
    Logger.info('headers = ${options.headers}');
    Logger.info('params = ${options.data}');
    Logger.info('================ 请求数据结束 ================');
    return options;
  }, onResponse: (response) {
    Logger.info('================ 响应数据开始 ================');
    Logger.info('code = ${response.statusCode}');
    Logger.info('data = ${response.data}');
    Logger.info('path = ${response.request.baseUrl}${response.request.path}');
    Logger.info('================ 响应数据结束 ================\n');
    return response;
  }, onError: (DioError err) {
    Logger.error('================错误响应数据 ================');
    Logger.error('type = ${err.type}');
    Logger.error('message = ${err.message}');
    Logger.error('path = ${err.request.baseUrl}${err.request.path}');
    return err;
  });

  ///get请求
  ///[url]请求地址
  ///[query]请求参数
  ///[headers]请求头
  ///[contentType]请求类型（默认application/json）
  ///[options]dio其他配置
  Future get(String url, {Map<String, dynamic> query, Map headers, ContentType contentType, Options options}) {
    return _call(url, _Method.GET, query: query, headers: headers, contentType: contentType, options: options);
  }

  ///post请求
  ///[url]请求地址
  ///[data]请求参数
  ///[headers]请求头
  ///[contentType]请求类型（默认application/json）
  ///[options]dio其他配置
  Future post(String url, {dynamic data, Map headers, ContentType contentType, Options options}) {
    return _call(url, _Method.POST, data: data, headers: headers, contentType: contentType, options: options);
  }

  ///put
  ///[url]请求地址
  ///[data]请求参数
  ///[headers]请求头
  ///[contentType]请求类型（默认application/json）
  ///[options]dio其他配置
  Future put(String url, {dynamic data, Map headers, ContentType contentType, Options options}) {
    return _call(url, _Method.PUT, data: data, headers: headers, contentType: contentType, options: options);
  }

  Future _call(String url, _Method method,
      {Map<String, dynamic> query, dynamic data, Map headers, ContentType contentType, Options options}) async {
    headers ??= <String, dynamic>{};
    options ??= Options(
      headers: {},
    );
    options.headers ??= <String, dynamic>{};
    if (contentType != null) {
      switch (contentType) {
        case ContentType.JSON:
          options.contentType = Headers.jsonContentType;
          break;
        case ContentType.FORM_URL_ENCODED:
          options.contentType = Headers.formUrlEncodedContentType;
          break;
        case ContentType.MULTIPART_FORM_DATA:
          break;
      }
    } else {
      options.contentType = Headers.jsonContentType;
    }

    /// 修改 base url 地址
    String baseUrl = await HTTPConfigCache.getGatewayUrl();
    if (baseUrl.isNotEmpty && baseUrl != httpManager.baseURI) {
      httpManager.dio.options.baseUrl = baseUrl;
    }

    /// 测试，可以本地在此处修改为指定的后端网关地址
    // httpManager.dio.options.baseUrl = 'http://172.16.3.32:8085';
    //httpManager.dio.options.baseUrl = 'http://172.16.3.100:10005';
    //httpManager.dio.options.baseUrl = 'http://172.16.3.41:8100/';
    //httpManager.dio.options.baseUrl = 'http://172.16.3.32:10000/';
    //httpManager.dio.options.baseUrl = 'http://172.16.3.50:18087/';//贺琳琳
    // httpManager.dio.options.baseUrl = 'http://172.16.3.55:8099/';//陈浩

    Map<String, String> oauth = await getOAuthInfo();
    String token = oauth['token'];
    String product = oauth['product'];
    String appKey = oauth['appKey'];
    headers['token'] = token;
    headers['product'] = product;
    headers['appKey'] = appKey;
    options.headers.addAll(headers);
    Response response;
    switch (method) {
      case _Method.GET:
        response = await httpManager.fetch(url, query: query, options: options);
        break;
      case _Method.POST:
        response = await httpManager.post(url, data: data, options: options);
        break;
      case _Method.PUT:
        response = await httpManager.put(url, data: data, options: options);
        break;
    }
    if (response == null) {
      ToastUtils.showToast('请求失败！！错误码：404');
      return null;
    }


    final int statusCode = response.statusCode;
    if (statusCode == 401 && response.data['message'] == '登录信息失效，请重新登录') {
      ToastUtils.showToast('当前账号已在其他地方登陆！');
      Get.offAll('/');
      return null;
    }
    if (statusCode != 200) {
      ToastUtils.showToast('请求失败！！错误码：$statusCode');
      return null;
    }
    if (response.data == null) {
      ToastUtils.showToast('响应数据为空！！');
      return null;
    }

    final int status = response.data['status'];
    switch (status) {
      case 200: //响应成功
        //兼容老系统
        if (response.data['dataList'] != null) {
          if (response.data['result'] != null && response.data['result'].toLowerCase() == 'success') {
            return response.data['dataList'];
          } else {
            ToastUtils.showToast(response.data['devMessage'] ?? '');
            return null;
          }
        } else {
          return response.data['result'];
        }
        break;
      case 409: //其他地方登录，强制下线并清除缓存
        ToastUtils.showToast('当前账号已在其他地方登陆！');
        Get.offAll('/');
        //sp.remove(GlobalConst.USER_TOKEN);
        break;
      case 401: //登录信息失效
        ToastUtils.showToast('登录信息失效，请重新登录！');
        Get.offAll('/');
        //sp.remove(GlobalConst.USER_TOKEN);
        break;
      case 500:
        // 后端接口错误
        ToastUtils.showToast(response.data['devMessage'] ?? ERROR_CODE[status]);
        Logger.error('================500 ================');
        Logger.error('message = ${response.data}');
        Logger.error('path =${response.request.path}');
        Logger.error('================500 ================');
        return null;
      default:

        /// 其他错误&兼容无响应码包装的接口
        return response.data;
    }
  }
}
