import 'dart:async';
import 'dart:convert';
import 'dart:js_util';
import 'package:get_it/get_it.dart';
import 'package:http/http.dart' as http;
import 'package:localstorage/localstorage.dart';
import 'package:sprintf/sprintf.dart';
import 'package:ustest/Services/LocalStorageService.dart';
import 'dart:typed_data';

import 'package:web_socket_channel/web_socket_channel.dart';

import 'AppSettings.dart';

class UserService {
  late User currentUser;
  final String UserStroageKey = "CurrentUser";
  final LocalStorage storage = new LocalStorage('UserStroage');
  late WebSocketChannel? Channel = WebSocketChannel.connect(
    Uri.parse('ws://192.168.6.80:9301?token=${currentUser.accessToken}'),
  ); //TODO

  User? getCurrentUser() {
    //if (currentUser != null) //TODO workaround
    //{
    //  if (currentUser?.userName != 'notlogin') {
    //    return currentUser;
    //  }
    //}

    // this.storage.deleteItem(UserStroageKey);
    var value = this.storage.getItem(UserStroageKey);
    if (value != null) {
      print('getCurrentUser value:' + value.toString());
      currentUser = User.fromJson(value);
    } else {
      print('getCurrentUser value: null');
      currentUser =
          new User(userName: 'notlogin', accessToken: '', organizationCode: '');
    }

    return currentUser;
  }

  void UpdateCurrentUserDetail() async {
    var user = getCurrentUser();
    if (user != null) {
      var token = user.accessToken;
      var body = sprintf(
          '{"jsonrpc": "2.0", "method": "GetUserInfoAsync", "params": [{"Token": "%s" }], "id": 1 }',
          [token]);
      var client = http.Client();
      var response = await client
          .post(Uri.parse(AppSettings.host + '/IUserService'), body: body);
      print('GetUserInfoAsync response.body' + response.body);
      var parsed = jsonDecode(response.body);
      if (parsed != null) {
        user.organizationCode = parsed['result']['OrganizationCode'];
        var jsonUser = user.toJson();

        this.storage.setItem(UserStroageKey, jsonUser);
        var userAgenter = UserAgentClient(client, token);

        print('jsonUser:' + jsonUser.toString());
        var url = Uri.parse(AppSettings.host);
        var wsUrl = 'ws://${url.host}:9301?token=$token';
        print("wsUrl---" + wsUrl);
        Channel = WebSocketChannel.connect(
          Uri.parse(wsUrl),
        );
      }
    }
  }

  logout() {
    this.storage.deleteItem(UserStroageKey);
  }

  Future<bool> signInAsync(
      String host, String userName, String password) async {
    AppSettings.host = host;
    var client = http.Client();
    var body = sprintf(
        '{"jsonrpc": "2.0", "method": "CommonLoginAsync", "params": [{"AnyAccount": "%s", "AnyCode": "", "Password": "%s" }], "id": 1 }',
        [userName, password]);
    var response = await client
        .post(Uri.parse(AppSettings.host + '/ILoginService'), body: body);
    print('response.body' + response.body);
    var parsed = jsonDecode(response.body);
    var token = parsed['result']['Token'];
    if (token != null) {
      var user = new User(
          userName: userName, accessToken: token, organizationCode: '');
      var jsonUser = user.toJson();

      this.storage.setItem(UserStroageKey, jsonUser);
      return true;
    }

    return false;
  }

  dynamic post(
      http.Client client, String interface, String method, String args) async {
    final body = sprintf(
        '{"jsonrpc": "2.0", "method": "GetUserInfoAsync", "params": %s, "id": 1 }',
        args);
    final response = await client
        .post(Uri.parse(AppSettings.host + '/$interface'), body: body);
    print('GetUserInfoAsync response.body' + response.body);
    var parsed = jsonDecode(response.body);
  }
}

class UserAgentClient extends http.BaseClient {
  //final String userAgent;
  final http.Client _inner;
  final String token;
  late Timer? _timer;
  UserAgentClient(this._inner, this.token) {
    print('heartrate client');
    //cancelTimer();
    final Duration duration = Duration(seconds: 300);
    _timer = Timer(duration, () => Run());
    Run();
  }

  Future<http.StreamedResponse> send(http.BaseRequest request) {
    //request.headers['user-agent'] = userAgent;
    return _inner.send(request);
  }

  void Run() {
    //cancelTimer();
    // var request =
    //     http.Request('POST', Uri.parse(AppSettings.host + '/IUserService'));
    // request.body =
    //     '{"jsonrpc": "2.0", "method": "HeartRateAsync", "params": [{"Token": "$token" }], "id": 1 }';
    print('heartrate send');
    //Future<http.StreamedResponse> streamedResponse = send(request);
    // Future.sync(() => send(request).then((value) =>
    //     http.Response.fromStream(value)
    //         .then((response) => print('heartrate response:${response.body}'))));
    Future.sync(() => _inner
        .post(Uri.parse(AppSettings.host + '/IUserService'),
            body:
                '{"jsonrpc": "2.0", "method": "HeartRateAsync", "params": [{"Token": "$token" }], "id": 1 }')
        .then((response) => print('heartrate response:${response.body}')));
    //var parsed = jsonDecode(response.then((value) => {print(value)}));
    //return parsed['result'] as bool;
    print('heartrate send done');
  }

  void cancelTimer() {
    _timer?.cancel();
  }
}

class JsonRpcResult {}

class User {
  final String userName;
  final String accessToken;
  String organizationCode;

  User(
      {required this.userName,
      required this.accessToken,
      required this.organizationCode});
  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      userName: json['userName'] as String,
      accessToken: json['accessToken'] as String,
      organizationCode: json['organizationCode'] as String,
    );
  }

  Map<String, dynamic> toJson() => {
        "userName": userName,
        "accessToken": accessToken,
        "organizationCode": organizationCode,
      };
}