
import 'dart:convert';
import 'dart:io';

import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';

import 'constants.dart';
import '../utils/index.dart';
import '../utils/cache.dart';
import '../models/index.dart';

class Http {
  static Dio _dio = new Dio(BaseOptions(
    sendTimeout: 3500,
  ));

  static init() {
    var host = Cache.get("server");
    var type = Cache.get("server_type");
    if (type == null || host == null) return;
    _dio.options.baseUrl = type + host + "/";
    print("current server: ${_dio.options.baseUrl}");

    (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
        (client) {
      client.badCertificateCallback =
          (X509Certificate cert, String host, int port) {
        return true;
      };
    };
  }

  static Future get(String api) async {
    try {
      return await _process(await _dio.get(api));
    } on DioError catch (err) {
      print(err.message);
      throw NetError(err.message);
    }
  }

  static Future post(String api, { Map<String, dynamic> data }) async {
    try {
      return await _process(await _dio.post(api, data: FormData.fromMap(data)));
    } on DioError catch (err) {
      print(err.message);
      throw NetError(err.message);
    }
  }

  static Future<dynamic> _process(dynamic response) async {
    var resp = HttpResponse.fromJson(response.data);
    if (resp.code != 200) {
      throw NetError(resp.msg);
    }
    return resp.result;
  }

  static Future<UserInfo> login(Map<String, dynamic> data) async {
    data["type"] = "kefu";
    var response = await post("check", data: data);
    String token = response["token"];
    String refToken = response["refToken"];
    _dio.options.headers["token"] = token;

    Cache.set("token", token);
    Cache.set("refToken", refToken);
    print("login ok");

    return await auth();
  }

  static Future<UserInfo> autoLogin() async {
    var token = Cache.get("token");
    if (token == null) {
      throw NetError("no token");
    }
    print("auto login");

    _dio.options.headers["token"] = token;
    return await auth();
  }

  static Future<UserInfo> auth() async {
    await post("check_auth");
    print("auth ok");

    return await info();
  }

  static Future<UserInfo> info() async {
    var response = await get("kefuinfo");
    var customer = UserInfo.fromJson(response);
    AppData.set("info", customer);
    Cache.set("config", json.encode(customer));
    print("info ok");
    return customer;
  }

  static Future<List<HttpMessage>> getHistory(String id) async {
    var response = await get("messages?visitorId=$id&kefuId=${Cache.get("username")}");
    List<HttpMessage> messages = new List<HttpMessage>();
    response = response as List;
    for(var msg in response) {
      messages.add(HttpMessage.fromJson(msg));
    }

    return messages;
  }


  static Future sendMsg(String to, String msg) async {
    var data = {
      "type": "kefu",
      "from_id": AppData.get("info").id,
      "to_id": to,
      "content": msg,
    };
    return await post("message", data: data);
  }
}