import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import 'package:amos_flutter_api/logutils.dart';

import '../consts/http_config.dart';
import '../consts/route_category_front_component_const.dart';
import '../consts/url_const.dart';
import '../services/application.dart';
import 'flutter_toast.dart';
import 'user_info_manager.dart';

mixin HttpRequest {
  // 基本配置
  static final BaseOptions baseOptions =
      BaseOptions(connectTimeout: HttpConfig.timeout);
  static final Dio dio = Dio(baseOptions);
  // 登录
  static Future<T> login<T>({Map<String, dynamic> params}) {
    const headers = {'content-type': 'application/json'};
    return request(URLConst.login,
        method: 'post', headers: headers, params: params);
  }

  // 获取选择公司
  static Future<T> getSelectCompany<T>() {
    return commonRequest(URLConst.selectCompany);
  }

  // 保存选择公司
  static Future<T> saveCurCompany<T>({Map<String, dynamic> params}) {
    return commonRequest(URLConst.saveCurCompany,
        method: 'post', params: params);
  }

  // 获取仓库信息
  static Future<T> getWarehouseInfo<T>(String orgCode) {
    return commonRequest('${URLConst.getWarehouseInfo}$orgCode');
  }

  // 获取仓库位置树结构
  static Future<T> getWarehousePositionStructureTree<T>(String id) {
    return commonRequest('${URLConst.getWarehousePosition}$id');
  }

  // 获取全量位置树结构
  static Future<T> getHiddenPositionStructureTree<T>(code) {
    return commonRequest(URLConst.getAllAddress+'/$code/treeNew');
  }

// 获取全量位置树结构
  static Future<T> companyTreeByUserAndType<T>() {
    return commonRequest(URLConst.companyTreeByUserAndType);
  }

  // 损耗获取车辆列表
  static Future<T> wasteQueryCarList<T>() {
    return commonRequest(URLConst.wasteQueryCarList);
  }

  // 获取车载灭火药剂
  static Future<T> getExtinguishAgent<T>(
      {Map<String, dynamic> params, String code}) {
    final commonParams = {'pageSize': HttpConfig.pageSize, 'code': code};
    commonParams.addAll(params);
    return commonRequest(URLConst.getExtinguishAgent,
        params: commonParams, queryParams: true);
  }

  // 全局二维码扫描
  static Future<T> queryQRInfo<T>(String type, {Map<String, dynamic> params}) {
    final commonParams = {'type': type};
    commonParams.addAll(params);
    return commonRequest(URLConst.queryQRInfo,
        params: commonParams, method: 'post');
  }

  // 获取灭火药剂入库的列表数据
  static Future<T> getStockDetailCategory<T>(
      {Map<String, dynamic> params, String category = '40000000'}) {
    final commonParams = {
      'pageSize': HttpConfig.pageSize,
      'category': category
    };
    commonParams.addAll(params);
    return commonRequest('${URLConst.getStockDetailCategory}',
        params: commonParams, queryParams: true);
  }

  // 获取灭火药剂装载的列表数据
  static Future<T> getStockDetailStock<T>(
      {Map<String, dynamic> params, String category = '40000000'}) {
    final commonParams = {
      'pageSize': HttpConfig.pageSize,
      'category': category
    };
    commonParams.addAll(params);
    return commonRequest('${URLConst.getStockDetailStock}',
        params: commonParams, queryParams: true);
  }

  // 灭火药剂入账
  static Future<T> fireAgentInStock<T>({List params}) {
    return commonRequest('${URLConst.fireAgentInStock}',
        dataParams: params, method: 'post');
  }

  // 灭火药剂装载提交
  static Future<T> lossExtinguishantsSubmit<T>(String carId, {List params}) {
    return commonRequest('equip/car/$carId/loss-extinguishants',
        dataParams: params, method: 'post');
  }

  // 查询报废单
  // 灭火药剂 billType=3
  static Future<T> checkScrapList<T>({Map<String, dynamic> params}) {
    final commonParams = {'pageSize': HttpConfig.pageSize, 'status': 0};
    commonParams.addAll(params);
    return commonRequest('${URLConst.checkScrapList}',
        params: commonParams, queryParams: true);
  }

  // 灭火药剂装载
  static Future<T> loadingExtinguishantSubmit<T>(String carId, {List params}) {
    return commonRequest('equip/car/$carId/loading-extinguishant',
        dataParams: params, method: 'post');
  }

  // 新建报废
  static Future<T> createScrapSubmit<T>({List params}) {
    return commonRequest('${URLConst.createScrapSubmit}',
        dataParams: params, method: 'post');
  }

  // 报废单详情列表
  static Future<T> scrapDetailList<T>({Map<String, dynamic> params}) {
    return commonRequest('${URLConst.scrapDetailList}',
        params: params, queryParams: true, method: 'post');
  }

  // 执行报废
  static Future<T> scrapExec<T>({Map<String, dynamic> params}) {
    return commonRequest(URLConst.scrapExec, params: params, method: 'post');
  }

  // 车辆装备  装载/卸载
  static Future<T> loadingOrUnloadEquip<T>({Map<String, dynamic> params}) {
    return commonRequest(URLConst.loadingOrUnloadEquip,
        params: params, method: 'post');
  }

  // 车辆保养
  static Future<T> carMaintain<T>({List params}) {
    return commonRequest(URLConst.carMaintain,
        dataParams: params, method: 'post');
  }

  // 车辆维修
  static Future<T> carRepair<T>({List params}) {
    return commonRequest(URLConst.carRepair,
        dataParams: params, method: 'post');
  }

  // 车辆维修完成
  static Future<T> carRepairComplete<T>({List params}) {
    return commonRequest(URLConst.carRepairComplete,
        dataParams: params, method: 'post');
  }

  // 车辆新建报废
  static Future<T> carCreateScrap<T>({List params}) {
    return commonRequest(URLConst.carCreateScrap,
        dataParams: params, method: 'post');
  }

  // 获取报废原因
  static Future<T> getScrapReason<T>() {
    return commonRequest('${URLConst.getScrapReason}');
  }

  // 装备入账
  static Future<T> equipStockIn<T>({List params}) {
    return commonRequest('${URLConst.equipStockIn}',
        dataParams: params, method: 'post');
  }

  // 装备保养 维修、维修完成统一接口
  static Future<T> equipHandle<T>(String item, {List params}) {
    String url = '';
    if (item == RouteItemFrontComponentConst.maintain) {
      url = '${URLConst.equipMaintain}';
    }
    if (item == RouteItemFrontComponentConst.repair) {
      url = '${URLConst.equipRepair}';
    }
    if (item == RouteItemFrontComponentConst.repaired) {
      url = '${URLConst.equipRepairComplete}';
    }
    if (item == RouteItemFrontComponentConst.scraped) {
      url = '${URLConst.equipScrap}';
    }
    return commonRequest(url, dataParams: params, method: 'post');
  }

  // 装备保养
  static Future<T> equipMaintain<T>({List params}) {
    return commonRequest('${URLConst.equipMaintain}',
        dataParams: params, method: 'post');
  }

  // 装装备维修
  static Future<T> equipRepair<T>({List params}) {
    return commonRequest('${URLConst.equipRepair}',
        dataParams: params, method: 'post');
  }

  // 装备维修完成
  static Future<T> equipRepairComplete<T>({List params}) {
    return commonRequest('${URLConst.equipRepairComplete}',
        dataParams: params, method: 'post');
  }

  // 查询灭火药剂分类列表
  static Future<T> queryClassificationFireAgent<T>(String id) {
    return commonRequest('${URLConst.queryClassificationFireAgent}$id');
  }

  // 基本分类统计
  static Future<T> queryStatisticsAllCategoryBase<T>(String id) {
    return commonRequest('${URLConst.queryStatisticsAllCategoryBase}$id');
  }

  // 装备状态统计
  static Future<T> queryEquipmentStatus<T>(String id) {
    return commonRequest('${URLConst.queryEquipmentStatus}$id');
  }

  // 消防车类别统计
  static Future<T> queryCarCategory<T>(String orgCode) {
    return commonRequest('${URLConst.queryCarCategory}$orgCode');
  }

  // 灭火药剂类别统计
  static Future<T> queryExtinguishingCategory<T>(String id) {
    return commonRequest('${URLConst.queryExtinguishingCategory}$id');
  }

  // 获取id
  static Future<T> getwarehouseId<T>() {
    return commonRequest(URLConst.getwarehouseId);
  }


  // 获取九大类类别
  static Future<T> queryEquipmentType<T>() {
    return commonRequest('${URLConst.queryEquipmentType}');
  }

  // 获取九大类二级分类
  static Future<T> queryEquipmentTypeCount<T>(String id) {
    return commonRequest('${URLConst.queryEquipmentTypeCount}$id');
  }

  // 获取装备三级分类
  static Future<T> queryEquipmentCount<T>(String id) {
    return commonRequest('${URLConst.queryEquipmentCount}$id');
  }

  // 获取车辆三级分类
  static Future<T> queryCarList<T>(String id,
      {@required String orgCode,
      String model = '',
      String carStateId = '',
      String brand = '',
      int pageNum = 0}) {
    final commonParams = {
      'orgcode': orgCode,
      'model': model,
      'carStateId': carStateId,
      'brand': brand,
      'pageNum': pageNum,
      'PageSize': HttpConfig.pageSize
    };
    return commonRequest('${URLConst.queryCarList}$id',
        params: commonParams, queryParams: true);
  }

  // 获取品牌列表
  static Future<T> getBrandList<T>(String type) {
    return commonRequest('${URLConst.getBrandList}$type');
  }

  // 获取车状态列表
  static Future<T> getStatusList<T>(String type) {
    return commonRequest('${URLConst.getStatusList}$type');
  }

  // 获取车规格列表
  static Future<T> getStandardList<T>() {
    return commonRequest('${URLConst.getStandardList}');
  }

  // 获取车辆详情
  static Future<T> getCarDetail<T>(String carId) {
    return commonRequest('${URLConst.getCarDetail}$carId');
  }

  // 装备 四级
  static Future<T> getEquipmentList<T>(String id, {String name}) {
    final commonParams = {'name': name};
    return commonRequest('${URLConst.getEquipmentList}$id',
        params: commonParams, queryParams: true);
  }

  // 上传图片
  static Future<T> uploadImage<T>({FormData data}) {
    return commonFormDataRequest(URLConst.uploadImage, formData: data);
  }

  // 获取消防车详情
  static Future<T> getCarDel<T>(String carId) {
    return commonRequest('${URLConst.getEquipCar}$carId');
  }

  // 获取装备详情
  static Future<T> getEquipDel<T>(String carId) {
    final commonParams = {
      'qrCode': carId,
    };
    return commonRequest(URLConst.getEquipment,
        params: commonParams, queryParams: true);
    // return commonRequest('${URLConst.getEquipment}$carId');
  }

  // 通用formData 数据上传
  static Future<T> commonFormDataRequest<T>(String url,
      {String method = 'post',
      FormData formData,
      Interceptor interceptor}) async {
    final baseInfo = await UserInfoManager.getLoginBaseInfo();
    final headers = {
      'product': '${baseInfo['product']}',
      'token': '${baseInfo['token']}',
      'appKey': '${baseInfo['appKey']}'
    };
    // 设置
    baseOptions.baseUrl = await HttpConfig.getBaseUrl();
    final options = Options(method: method);

    options.headers.addAll(headers);

    Interceptor dInter = InterceptorsWrapper(onRequest: (options) {
      print(
          '\n================================= 请求数据 =================================');
      print('method = ${options.method.toString()}');
      print('url = ${options.uri.toString()}');
      print('headers = ${options.headers}');
      print('params = ${options.data}');
      return options;
    }, onResponse: (response) {
      print(
          '\n================================= 响应数据开始 =================================');
      print('code = ${response.statusCode}');
      LogUtil.d('data = ${response.data}');
      print(
          '================================= 响应数据结束 =================================\n');
      return response;
    }, onError: (DioError err) {
      print(
          '\n=================================错误响应数据 =================================');
      print('type = ${err.type}');
      print('message = ${err.message}');
      print('\n');
      return err;
    });

    List<Interceptor> inters = [dInter];
    if (interceptor != null) {
      inters.add(interceptor);
    }

    dio.interceptors.addAll(inters);

    try {
      Response response =
          await dio.request(url, data: formData, options: options);
      final data = response.data;
      // 统一拦截接口非200的情况
      final status = data['status'];

      if (status != 200) {
        //账号其他地方登陆，跳到登录页
        // TODO: 处理本地数据缓存问题
        if (status == 403) {
          UserInfoManager.logoutClear();
        }
        String message = data['message'];
        if (message != null && message.isNotEmpty) {
          shortMessage(message);
        } else {
          shortMessage('接口请求失败!');
        }
      }
      return response.data;
    } on DioError catch (err) {
      if (err.type == DioErrorType.CONNECT_TIMEOUT) {
        shortMessage('请求超时!');
      } else {
        shortMessage('请求接口失败!');
      }
      return Future.error(err);
    }
  }

  // 通用请求
  static Future<T> commonRequest<T>(String url,
      {String method = 'get',
      Map<String, dynamic> params,
      bool queryParams = false,
      List dataParams,
      Interceptor interceptor}) async {
    final baseInfo = await UserInfoManager.getLoginBaseInfo();
    final headers = {
      'product': '${baseInfo['product']}',
      'token': '${baseInfo['token']}',
      'appKey': '${baseInfo['appKey']}'
    };
    return request(url,
        method: method,
        headers: headers,
        params: params,
        interceptor: interceptor,
        queryParams: queryParams,
        dataParams: dataParams);
  }

  static Future<T> request<T>(String url,
      {String method = 'get',
      Map<String, dynamic> headers,
      Map<String, dynamic> params,
      bool queryParams = false,
      List dataParams,
      Interceptor interceptor}) async {
    // 设置
    baseOptions.baseUrl = await HttpConfig.getBaseUrl();
    final options = Options(method: method);

    options.headers.addAll(headers);

    Interceptor dInter = InterceptorsWrapper(onRequest: (options) {
      print(
          '\n================================= 请求数据 =================================');
      print('method = ${options.method.toString()}');
      print('url = ${options.uri.toString()}');
      print('headers = ${options.headers}');
      print('params = ${options.data}');
      return options;
    }, onResponse: (response) {
      print(
          '\n================================= 响应数据开始 =================================');
      print('code = ${response.statusCode}');
      LogUtil.d('data = ${response.data}');
      print(
          '================================= 响应数据结束 =================================\n');
      return response;
    }, onError: (DioError err) {
      print(
          '\n=================================错误响应数据 =================================');
      print('type = ${err.type}');
      print('message = ${err.message}');
      print('\n');
      return err;
    });

    List<Interceptor> inters = [dInter];
    if (interceptor != null) {
      inters.add(interceptor);
    }

    dio.interceptors.addAll(inters);

    try {
      Response response = await dio.request(url,
          data: queryParams ? null : params ?? dataParams,
          options: options,
          queryParameters: queryParams ? params : null);
      final data = response.data;
      // 统一拦截接口非200的情况
      final status = data['status'];

      if (status != 200) {
        //账号其他地方登陆，跳到登录页
        // 清楚本地数据缓存
        if (status == 403) {
          UserInfoManager.clearBaseInfoMemoryCache();
          Application.goToLogin();
        }
        String message = data['message'];
        if (message != null && message.isNotEmpty) {
          FlutterToast.toastBottom(message);
        } else {
          FlutterToast.toastBottom('接口请求失败!');
        }
      }
      return response.data;
    } on DioError catch (err) {
      if (err.type == DioErrorType.CONNECT_TIMEOUT) {
        FlutterToast.toastBottom('请求超时!');
      } else {
        FlutterToast.toastBottom('请求接口失败!');
      }
      return Future.error(err);
    }
  }
}
