import 'package:flutter/widgets.dart';
import 'package:guru_utils/device/device_utils.dart';
import 'package:guru_utils/log/log.dart';

import 'package:json_annotation/json_annotation.dart';

/// Created by Haoyi on 2020/7/31
///

part 'device_info.g.dart';

class LocaleInfo {
  final String languageCode;
  final String script;
  final String countryCode;

  const LocaleInfo(this.languageCode, this.script, this.countryCode);

  String get fullTag => "$languageCode-$script-$countryCode";

  String get languageAndCountry => "$languageCode-$countryCode";
}

// 上报用户信息
@JsonSerializable()
class DeviceInfo {
  @JsonKey(defaultValue: "")
  final String androidId;

  @JsonKey(defaultValue: "")
  final String appIdentifier;

  @JsonKey(defaultValue: "")
  final String appVersion;

  @JsonKey(defaultValue: "")
  final String brand;

  @JsonKey(defaultValue: "")
  final String deviceCountry;

  @JsonKey(defaultValue: "")
  final String deviceId;

  @JsonKey(defaultValue: "")
  final String deviceType;

  @JsonKey(defaultValue: "")
  final String language;

  @JsonKey(defaultValue: "")
  final String locale;

  @JsonKey(defaultValue: "")
  final String model;

  // 后端的,不用管
  // final String pushDeviceType;

  @JsonKey(defaultValue: true)
  final bool pushNotificationEnable = true;

  // pushNotifications

  @JsonKey(name: "pushType", defaultValue: "FCM")
  final String pushType;

  @JsonKey(defaultValue: "")
  final String timezone;

  @JsonKey(defaultValue: "")
  String uid;

  @JsonKey(defaultValue: "")
  String deviceToken;

  DeviceInfo({
    required this.appIdentifier,
    required this.appVersion,
    required this.brand,
    required this.deviceCountry,
    required this.deviceType,
    required this.language,
    required this.locale,
    required this.model,
    required this.timezone,
    required this.deviceId,
    this.pushType = 'FCM',
    this.androidId = '',
    this.uid = '',
    this.deviceToken = '',
  });

  static bool equals(DeviceInfo? deviceInfo1, DeviceInfo? deviceInfo2) {
    if (deviceInfo1 != null && deviceInfo2 != null) {
      return (deviceInfo1.appVersion == deviceInfo2.appVersion) &&
          (deviceInfo1.uid == deviceInfo2.uid) &&
          (deviceInfo1.deviceCountry == deviceInfo2.deviceCountry) &&
          (deviceInfo1.language == deviceInfo2.language) &&
          (deviceInfo1.locale == deviceInfo2.locale) &&
          (deviceInfo1.timezone == deviceInfo2.timezone) &&
          (deviceInfo1.deviceToken == deviceInfo2.deviceToken) &&
          (deviceInfo1.androidId == deviceInfo2.androidId) &&
          (deviceInfo1.deviceId == deviceInfo2.deviceId) &&
          (deviceInfo1.appIdentifier == deviceInfo2.appIdentifier) &&
          (deviceInfo1.brand == deviceInfo2.brand) &&
          (deviceInfo1.deviceType == deviceInfo2.deviceType) &&
          (deviceInfo1.model == deviceInfo2.model) &&
          (deviceInfo1.pushType == deviceInfo2.pushType);
    } else {
      return deviceInfo1 == deviceInfo2;
    }
  }

  bool get isValid => deviceToken.isNotEmpty && uid.isNotEmpty;

  factory DeviceInfo.fromJson(Map<String, dynamic> json) => _$DeviceInfoFromJson(json);

  Map<String, dynamic> toJson() => _$DeviceInfoToJson(this);

  void dumpDevice({String msg = "default"}) {
    Log.d("=============={$msg}==============");
    Log.d(" [androidId]: $androidId");
    Log.d(" [appIdentifier]: $appIdentifier");
    Log.d(" [appVersion]: $appVersion");
    Log.d(" [brand]: $brand");
    Log.d(" [deviceCountry]: $deviceCountry");
    Log.d(" [deviceId]: $deviceId");
    Log.d(" [deviceType]: $deviceType");
    Log.d(" [language]: $language");
    Log.d(" [model]: $model");
    Log.d(" [pushNotificationEnable]: $pushNotificationEnable");
    Log.d(" [pushType]: $pushType");
    Log.d(" [timezone]: $timezone");
    Log.d(" [uid]: $uid");
    Log.d(" [deviceToken]: $deviceToken");
    Log.d("=====================================");
  }

  @override
  String toString() {
    return 'DeviceInfo{androidId: $androidId, appIdentifier: $appIdentifier, appVersion: $appVersion, brand: $brand, deviceCountry: $deviceCountry, deviceId: $deviceId, deviceType: $deviceType, language: $language, locale: $locale, model: $model, pushNotificationEnable: $pushNotificationEnable, pushType: $pushType, timezone: $timezone, uid: $uid, deviceToken: $deviceToken}';
  }

  String toXDeviceInfo() {
    return "appIdentifier=$appIdentifier;appVersion=$appVersion;deviceType=$deviceType;deviceCountry=$deviceCountry;appCountry=${DeviceUtils.buildLocaleInfo().countryCode};local=$locale;language=$language;timezone=$timezone;brand=$brand;model=$model;androidId=$androidId";
  }
}

// // 收到 push 上报打点
// @JsonSerializable()
// class PushEventReqBody {
//   // yyyy-MM-ddTHH:mm:ssZ
//   @JsonKey(defaultValue: "")
//   final String appEventTime;
//
//   // 本机数据
//   final DeviceInfo deviceData;
//
//   //See PushEventType
//   @JsonKey(defaultValue: "")
//   final String eventType;
//
//   // 从 push data 中获取
//   @JsonKey(defaultValue: "")
//   final String pushEventId;
//
//   @JsonKey(defaultValue: "")
//   final String serverPushTime;
//
//   @JsonKey(defaultValue: "")
//   final String taskName;
//
//   PushEventReqBody(
//       {this.appEventTime,
//       this.deviceData,
//       this.eventType,
//       this.pushEventId,
//       this.serverPushTime,
//       this.taskName});
//
//   factory PushEventReqBody.fromJson(Map<String, dynamic> json) => _$PushEventReqBodyFromJson(json);
//
//   Map<String, dynamic> toJson() => _$PushEventReqBodyToJson(this);
// }

class DeviceTrack {
  final DeviceInfo? newDevice;
  final DeviceInfo? oldDevice;

  DeviceTrack(this.newDevice, this.oldDevice);

  DeviceInfo? get device => newDevice ?? oldDevice;

  bool get isChanged => !DeviceInfo.equals(newDevice, oldDevice);

// void dump() {
//   if (EventLogger.dumpLog) {
//     print("========== DeviceTrack ==========");
//     print("  [New][appVersion] ${newDevice?.appVersion}");
//     print("  [Old][appVersion] ${oldDevice?.appVersion}");
//     print("        >>>> diff result: ${newDevice?.appVersion == oldDevice?.appVersion}");
//     print("  [New][uid] ${newDevice?.uid}");
//     print("  [Old][uid] ${oldDevice?.uid}");
//     print("        >>>> diff result: ${newDevice?.uid == oldDevice?.uid}");
//     print("  [New][deviceCountry] ${newDevice?.deviceCountry}");
//     print("  [Old][deviceCountry] ${oldDevice?.deviceCountry}");
//     print("        >>>> diff result: ${newDevice?.deviceCountry == oldDevice?.deviceCountry}");
//     print("  [New][language] ${newDevice?.language}");
//     print("  [Old][language] ${oldDevice?.language}");
//     print("        >>>> diff result: ${newDevice?.language == oldDevice?.language}");
//     print("  [New][locale] ${newDevice?.locale}");
//     print("  [Old][locale] ${oldDevice?.locale}");
//     print("        >>>> diff result: ${newDevice?.locale == oldDevice?.locale}");
//     print("  [New][timezone] ${newDevice?.timezone}");
//     print("  [Old][timezone] ${oldDevice?.timezone}");
//     print("        >>>> diff result: ${newDevice?.timezone == oldDevice?.timezone}");
//     print("  [New][deviceToken] ${newDevice?.deviceToken}");
//     print("  [Old][deviceToken] ${oldDevice?.deviceToken}");
//     print("        >>>> diff result: ${newDevice?.deviceToken == oldDevice?.deviceToken}");
//     print("  [New][androidId] ${newDevice?.androidId}");
//     print("  [Old][androidId] ${oldDevice?.androidId}");
//     print("        >>>> diff result: ${newDevice?.androidId == oldDevice?.androidId}");
//     print("  [New][deviceId] ${newDevice?.deviceId}");
//     print("  [Old][deviceId] ${oldDevice?.deviceId}");
//     print("        >>>> diff result: ${newDevice?.deviceId == oldDevice?.deviceId}");
//     print("  [New][appIdentifier] ${newDevice?.appIdentifier}");
//     print("  [Old][appIdentifier] ${oldDevice?.appIdentifier}");
//     print("        >>>> diff result: ${newDevice?.appIdentifier == oldDevice?.appIdentifier}");
//     print("  [New][brand] ${newDevice?.brand}");
//     print("  [Old][brand] ${oldDevice?.brand}");
//     print("        >>>> diff result: ${newDevice?.brand == oldDevice?.brand}");
//     print("  [New][deviceType] ${newDevice?.deviceType}");
//     print("  [Old][deviceType] ${oldDevice?.deviceType}");
//     print("        >>>> diff result: ${newDevice?.deviceType == oldDevice?.deviceType}");
//     print("  [New][model] ${newDevice?.model}");
//     print("  [Old][model] ${oldDevice?.model}");
//     print("        >>>> diff result: ${newDevice?.model == oldDevice?.model}");
//     print("  [New][pushType] ${newDevice?.pushType}");
//     print("  [Old][pushType] ${oldDevice?.pushType}");
//     print("        >>>> diff result: ${newDevice?.pushType == oldDevice?.pushType}");
//     print("========== DeviceTrack ==========");
//   }
// }
}
