import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:amap_location/amap_location.dart';
import 'package:apple_sign_in/apple_sign_in.dart';
import 'package:chat/data/WebData.dart';
import 'package:chat/data/chat_data_mgr.dart';
import 'package:chat/data/constants.dart';
import 'package:chat/data/group_data_mgr.dart';
import 'package:chat/home/homeMain.dart';
import 'package:chat/home/splash_page.dart';
import 'package:chat/models/gift_select_provider.dart';
import 'package:chat/models/money_change.dart';
import 'package:chat/models/ref_name_provider.dart';
import 'package:chat/utils/MessageMgr.dart';
import 'package:chat/utils/NetUtil.dart';
import 'package:chat/utils/OtherLogin.dart';
import 'package:chat/utils/file_cache_mgr.dart';
import 'package:chat/utils/flutter_windowmanager.dart';
import 'package:chat/utils/local_notification_util.dart';
import 'package:chat/utils/msgHandler.dart';
import 'package:chat/utils/receive_share_file.dart';
import 'package:chat/utils/screen.dart';
import 'package:chat/utils/screen_shot.dart';
import 'package:chat/utils/sound_util.dart';
import 'package:chat/utils/sp_utils.dart';
import 'package:chat/utils/sql_util.dart';
import 'package:easy_contact_picker/easy_contact_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bugly/flutter_bugly.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
//import 'package:flutter_bugly/flutter_bugly.dart';
import 'package:location_permissions/location_permissions.dart' as lp;
import 'package:package_info/package_info.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:oktoast/oktoast.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'home/IndexPage.dart';
import 'generated/i18n.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:fluwx_no_pay/fluwx_no_pay.dart' as fluwx;
import 'package:chat/data/UserData.dart' show UserData;
import 'package:auto_orientation/auto_orientation.dart';

import 'models/voucher_change.dart';

//读取本地数据
initLocalData() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();

  var localUserId = prefs.getInt(Constants.LocalUserId);
  if (localUserId != null) {
    print('用户不为空');
    //设置用户基本信息
    UserData().basicInfo.userId = localUserId;
    String localUserData = await SPUtils.get(Constants.LocalUsrInfo);
    if (localUserData != null) {
      UserData().fromLocalJson(json.decode(localUserData));
    }

    //读取好友信息
    //读取聊天信息
    await ChatDataMgr().initMsg();
    //读取群信息
    await GroupInfoMgr().initLocalGroupList();
  }
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  LocalNotificationUtil.instance.initJPush();
  LocalNotificationUtil.instance.initLocalPush();

  await FileCacheMgr.initPathKey();
  await SqlUtil.init();
  await initLocalData();

  AutoOrientation.portraitUpMode();
  AMapLocationClient.setApiKey("3f4c9fca5f513ac0be361e92d8586ff3");
  AMapLocationClient.startup(new AMapLocationOption(
      desiredAccuracy: CLLocationAccuracy.kCLLocationAccuracyHundredMeters));
  setStatusBar();

  FlutterBugly.init(androidAppId: "d2a8d2c6a0", iOSAppId: "f0ad7340d0");

  FlutterBugly.postCatchedException(() {
    runApp(MyApp());
  }, debugUpload: true);

//  runApp(RestartWidget(
//    child: MyApp(),
//  ));
}

void setCustomErrorPage(BuildContext context) {
  ErrorWidget.builder = (FlutterErrorDetails flutterErrorDetails) {
    print(flutterErrorDetails.toString());
    return Scaffold(
      body: Center(
          child: Column(
        children: <Widget>[
          Container(
            margin: EdgeInsets.only(
                top: ScreenUtil.instance.setHeight(180),
                bottom: ScreenUtil.instance.setHeight(49)),
            child: Image.asset(
              'assets/images/net_error.png',
              width: ScreenUtil.instance.setWidth(150),
            ),
          ),
          Container(
            margin: EdgeInsets.only(top: ScreenUtil().setHeight(50)),
            child: Text(
              I18n.of(Constants.getCurrentContext()).server_error_tips,
              textScaleFactor: 1.0,
              style: TextStyle(color: Color(0xFF8F8E8E), fontSize: 18),
            ),
          ),
        ],
      )),
    );
  };
}

Map<String, int> language = {
  'en_US': LanguageType.English,
  'en_CN': LanguageType.English,
  'vi_VN': LanguageType.Vietnamese,
  'vi_CN': LanguageType.Vietnamese,
  'vi_US': LanguageType.Vietnamese,
  'zh_Hant_CN': LanguageType.TraditionalChinese,
  'zh_TW': LanguageType.TraditionalChinese,
  'zh_HK': LanguageType.TraditionalChinese,
  'zh_Hant': LanguageType.TraditionalChinese,
  'zh_Hant_MO': LanguageType.TraditionalChinese,
  'zh_Hant_TW': LanguageType.TraditionalChinese,
  'zh_Hant_HK': LanguageType.TraditionalChinese,
  'zh_Hant_US': LanguageType.TraditionalChinese,
  'zh_Hans': LanguageType.SimplifiedChinese,
  'zh_Hans_CN': LanguageType.SimplifiedChinese,
  'zh_Hans_US': LanguageType.SimplifiedChinese,
  'zh_Hans_MO': LanguageType.SimplifiedChinese,
  'zh_Hans_SG': LanguageType.SimplifiedChinese,
  'zh_Hans_VN': LanguageType.SimplifiedChinese,
  'zh_CN': LanguageType.SimplifiedChinese,
  'ko_KR': LanguageType.Korean,
  'ko_KP': LanguageType.Korean,
  'ko_Kore_CN': LanguageType.Korean,
  'ko_Kore_US': LanguageType.Korean,
  'ko_CN': LanguageType.Korean,
  'ja_JP': LanguageType.Japanese,
  'ja_US': LanguageType.Japanese,
  'ja_CN': LanguageType.Japanese,
};

//全局去掉水波纹
class NoSplashFactory extends InteractiveInkFeatureFactory {
  const NoSplashFactory();

  InteractiveInkFeature create({
    @required MaterialInkController controller,
    @required RenderBox referenceBox,
    @required Offset position,
    @required Color color,
    TextDirection textDirection,
    bool containedInkWell: false,
    RectCallback rectCallback,
    BorderRadius borderRadius,
    ShapeBorder customBorder,
    double radius,
    VoidCallback onRemoved,
  }) {
    return new NoSplash(
      controller: controller,
      referenceBox: referenceBox,
      color: color,
      onRemoved: onRemoved,
    );
  }
}

class NoSplash extends InteractiveInkFeature {
  NoSplash({
    @required MaterialInkController controller,
    @required RenderBox referenceBox,
    Color color,
    VoidCallback onRemoved,
  })  : assert(controller != null),
        assert(referenceBox != null),
        super(
            controller: controller,
            referenceBox: referenceBox,
            onRemoved: onRemoved) {
    controller.addInkFeature(this);
  }
  @override
  void paintFeature(Canvas canvas, Matrix4 transform) {}
}

class FallbackCupertinoLocalisationsDelegate
    extends LocalizationsDelegate<CupertinoLocalizations> {
  const FallbackCupertinoLocalisationsDelegate();

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<CupertinoLocalizations> load(Locale locale) =>
      DefaultCupertinoLocalizations.load(locale);

  @override
  bool shouldReload(FallbackCupertinoLocalisationsDelegate old) => false;
}

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  final i18n = I18n.delegate;
  RefNameProvider _refNameProvider;
  bool isOpen = true;

  @override
  void initState() {
    super.initState();

    setCustomErrorPage(context);
    isAvailableAppleSignIn();
    Screen.initFactor();

    initVersionName();

    askLocationPermission();
    I18n.onLocaleChanged = onLocaleChange;
    WidgetsBinding.instance.addObserver(this);
    ReceiveShareFile.init();
    ScreenShot.getFileStream();
  }

  isAvailableAppleSignIn() async {
    isOpen = (await SPUtils.getBool(Constants.Splash_OPENED)) ?? false;
    OtherLogin.isAvailableForAppleSignIn = await AppleSignIn.isAvailable();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (_refNameProvider == null) {
      _refNameProvider = RefNameProvider();
    }
  }

  initVersionName() async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    Constants.versionName = packageInfo.version;
    Constants.packageName = packageInfo.packageName;
  }

  @override
  void dispose() {
    //positionStream?.cancel();
    WidgetsBinding.instance.removeObserver(this);
//    LocalNotificationUtil.instance.dispose();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) async {
    print("--" + state.toString());
    switch (state) {
      case AppLifecycleState.inactive: // 处于这种状态的应用程序应该假设它们可能在任何时候暂停。
        break;
      case AppLifecycleState.resumed: // 应用程序可见，前台
        setStatusBar();
        print('切换到前台');
        //检测用户是否开启定位权限
        MessageMgr().emit('test_Permission');
        NetWork().checkConnect();
        MessageMgr().emit(MessageMgr.REFRESH_PUSH_PERMISSION);
        LocalNotificationUtil.isBackground = false;
        LocalNotificationUtil.instance.cleanAllNotifications();
        if (UserData().isBannerStatus) {
          UserData().isBannerStatus = false;
          MessageMgr().emit('refresh_money');
        }

        if (MsgHandler.audioChatRequestFriendId > 0) {
          MessageMgr().emit(
              'Receive AudioChat Request', MsgHandler.audioChatRequestFriendId);
        }
        break;
      case AppLifecycleState.paused: // 应用程序不可见，后台
        print('切换到后台');
        LocalNotificationUtil.isBackground = true;
        SoundUtils.instance.pause();
        if (Platform.isIOS) NetWork().reallyClose();

        ///iOS切后台关闭socket不然会闪退
        break;
//      case AppLifecycleState.suspending: // 申请将暂时暂停
//        print('程序挂起');
//        break;
      case AppLifecycleState.detached: // 申请将暂时暂停
//        print('程序挂起');
        break;
    }
  }

  void onLocaleChange(Locale locale) {
    final String lang = locale != null ? locale.toString() : "";
    print('#### onLocaleChange $lang');
    setState(() {
      I18n.locale = locale;
    });
  }

  setDisableScreenshots() async {
    print('Platform.isAndroid ${Platform.isAndroid}');
    if (Platform.isAndroid) {
      await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE);
    }
  }

  @override
  Widget build(BuildContext context) {
    fluwx.registerWxApi(
        appId: Constants.AppId,
        universalLink: "https://www.xxx.com/iosuniversallink/");
    return OKToast(
        child: MultiProvider(
            providers: [
          ChangeNotifierProvider(create: (_) => GiftSelectProvider()),
          ChangeNotifierProvider(create: (_) => MoneyChangeProvider()),
          ChangeNotifierProvider(create: (_) => _refNameProvider),
          ChangeNotifierProvider(create: (_) => VoucherChangeProvider()),
        ],
            child: MaterialApp(
              theme: ThemeData(
                platform: TargetPlatform.iOS,
                highlightColor: Colors.transparent,
                splashFactory: const NoSplashFactory(),
                toggleableActiveColor: Constants.BlueTextColor,
                scaffoldBackgroundColor: Constants.GreyBackgroundColor,
                accentColor: Constants.BlueTextColor,
                indicatorColor: Constants.BlueTextColor,
                tabBarTheme: TabBarTheme(
                  indicatorSize: TabBarIndicatorSize.label,
                  labelColor: Constants.BlueTextColor,
                  unselectedLabelColor: Constants.GreyTextColor,
                  labelPadding: EdgeInsets.only(bottom: 5, left: 15, right: 15),
                  labelStyle:
                      TextStyle(fontWeight: FontWeight.w600, fontSize: 15),
                  unselectedLabelStyle:
                      TextStyle(fontWeight: FontWeight.w500, fontSize: 15),
                ),
                appBarTheme: AppBarTheme(
                    elevation: 0,
                    brightness: Brightness.light,
                    color: Colors.white,
                    iconTheme: IconThemeData(color: Colors.black),
                    actionsIconTheme: IconThemeData(color: Colors.black),
                    textTheme: TextTheme(
                        title: TextStyle(
                            color: Constants.BlackTextColor, fontSize: 20))),
                primaryColor: Constants.BlueTextColor,
                inputDecorationTheme: InputDecorationTheme(
                    labelStyle: TextStyle(
                        fontSize: 13, color: Constants.BlackTextColor),
                    border: InputBorder.none,
                    contentPadding: EdgeInsets.all(10),
                    hintStyle: TextStyle(
                        fontSize: 11,
                        color: Color.fromARGB(255, 192, 191, 191))),
              ),
              localizationsDelegates: [
                i18n,
                GlobalMaterialLocalizations.delegate,
                GlobalWidgetsLocalizations.delegate,
                GlobalCupertinoLocalizations.delegate, // <-- needed for iOS
                const FallbackCupertinoLocalisationsDelegate()
              ],
              //locale:  Locale("en", "US"),
              supportedLocales: i18n.supportedLocales,
              title: 'Chat',
              onGenerateTitle: (context) {
                // 此处
                return 'Hibok';
              },
              navigatorKey: Constants.navigatorKey,
              routes: <String, WidgetBuilder>{
                '/main': (BuildContext context) => HomeMain(),
              },
              home: Builder(builder: (context) {
                return goIndex();
              }),
              //home: IndexPage(),
              localeResolutionCallback: (deviceLocale, supportedLocales) {
                if (deviceLocale != null) {
                  final String lang =
                      deviceLocale != null ? deviceLocale.toString() : "";
                  print('#### fl:  $lang');
                  UserData().deviceLanguageCode = deviceLocale.toString();
                  //设置设备语言
                  if (language.containsKey(deviceLocale.toString()))
                    UserData().deviceLanguage =
                        language[deviceLocale.toString()];
                  getPosition(deviceLocale);
                }
                return deviceLocale;
              },
            )));
  }

  goIndex() {
    if (!isOpen) {
      return SplashPage();
    } else {
      return IndexPage();
    }
  }

  askLocationPermission() async {
    lp.PermissionStatus status =
        await lp.LocationPermissions().checkPermissionStatus();
    print('定位权限 $status');

    final PermissionStatus addStatus = await PermissionHandler()
        .checkPermissionStatus(PermissionGroup.contacts);

    print('通讯录权限 $addStatus');

    List<PermissionGroup> permissionList = [];
    if (status == lp.PermissionStatus.granted) {
      UserData().hasLocationPermission = true;
    } else {
      permissionList.add(PermissionGroup.locationWhenInUse);
    }
    if (addStatus == PermissionStatus.granted) {
      setContact();
    } else {
      if (Platform.isAndroid) {
//        ///ios隐藏
        permissionList.add(PermissionGroup.contacts);
      }
    }
    print(permissionList);
    if (permissionList.length != 0) {
      Map<PermissionGroup, PermissionStatus> permissionRequestResult =
          await PermissionHandler().requestPermissions(permissionList);
      var status = permissionRequestResult[PermissionGroup.locationWhenInUse];
      var addStatus = permissionRequestResult[PermissionGroup.contacts];
      if (status == PermissionStatus.granted) {
        UserData().hasLocationPermission = true;
      }
      if (addStatus == PermissionStatus.granted) {
        setContact();
      }
    }

    MessageMgr().emit('test_Permission');
  }

  setContact() async {
    final EasyContactPicker _contactPicker = new EasyContactPicker();
    List<Contact> _list = await _contactPicker.selectContacts();
    UserData().contactList.clear();
    _list.forEach((contack) {
      UserData()
          .contactList
          .add({'PhoneNumber': contack.phoneNumber, 'Name': contack.fullName});
    });
    MessageMgr().emit('PostContact');
  }

  void getPosition(deviceLocale) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var localLanguage = prefs.getInt(Constants.Language);
    print('localLanguage$localLanguage');
    if (localLanguage == null) {
      if (language.containsKey(deviceLocale.toString()))
        UserData().language = language[deviceLocale.toString()];
    } else {
      UserData().language = localLanguage;
    }
    WebData().getAllData();
    UserData().getCurrentPosition();
  }
}
