import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/logger.dart';
import 'package:aman_kassa_flutter/core/models/choice.dart';
import 'package:aman_kassa_flutter/core/models/response.dart';
import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
import 'package:aman_kassa_flutter/core/services/DataService.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/views/home/components/header_title.dart';
import 'package:aman_kassa_flutter/views/lockscreen/passcodescreen.dart';
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:logger/logger.dart';
import 'package:shared_preferences/shared_preferences.dart';

import './tabs/KassaTab.dart';
import './tabs/AdditionalTab.dart';
import './tabs/CalculatorTab.dart';

import './components/popup_menu.dart';
import './components/bottom_bar.dart';

class HomeView extends StatefulWidget {
  @override
  _HomeViewState createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
  Logger log = getLogger('HomeView');
  late PageController pageController;
  late int selectedTabIndex;
  DataService _dataService = locator<DataService>();
  ApiService _api = locator<ApiService>();
  NavigatorService _navigatorService = locator<NavigatorService>();
  final GlobalKey<State> _keyLoader = new GlobalKey<State>();

  final lastKnownStateKey = 'lastKnownStateKey';
  final backgroundedTimeKey = 'backgroundedTimeKey';
  final pinLockMillis = 2000; // 2 seconds

  Future _paused() async {
    final sp = await SharedPreferences.getInstance();
    sp.setInt(lastKnownStateKey, AppLifecycleState.paused.index);
  }

  Future _inactive() async {
    final sp = await SharedPreferences.getInstance();
    final prevState = sp.getInt(lastKnownStateKey);
    final prevStateIsNotPaused = prevState != null &&
        AppLifecycleState.values[prevState] != AppLifecycleState.paused;
    final bool pinIsExist = Redux.store!.state.settingState?.pinCode != null && Redux.store!.state.settingState!.pinCode!.length > 3;
    final bool pinSkipped = Redux.store!.state.settingState?.pinSkip == true;
    print('prevStateIsNotPaused=$prevStateIsNotPaused, pinIsExist=$pinIsExist, pinSkipped=$pinSkipped');
    if(prevStateIsNotPaused && pinSkipped == false && pinIsExist == true) {
      // save App backgrounded time to Shared preferences
      sp.setInt(backgroundedTimeKey, DateTime.now().millisecondsSinceEpoch);
    }
// update previous state as inactive
    sp.setInt(lastKnownStateKey, AppLifecycleState.inactive.index);
  }

  Future _resumed() async {
    final sp = await SharedPreferences.getInstance();
    final bgTime = sp.getInt(backgroundedTimeKey) ?? 0;
    final allowedBackgroundTime = bgTime + pinLockMillis;
    final shouldShowPIN = DateTime.now().millisecondsSinceEpoch > allowedBackgroundTime;
    if(shouldShowPIN && bgTime > 0) {
      await Redux.store!.dispatch(changePinLockedFromSetting(true));
      pushToLockScreen();
    }
    sp.remove(backgroundedTimeKey); // clean
    sp.setInt(lastKnownStateKey, AppLifecycleState.resumed.index);// previous state
  }

  void pushToLockScreen() {
    Navigator.of(context).push(MaterialPageRoute(
        builder: (_) =>
            WillPopScope(
                onWillPop: () async {
                  return false;
                },
                child: PassCodeScreen( title: 'Безопасность',)
            )
    ));
  }

  _checkLockPin () async {
    final bool pinIsExist = Redux.store!.state.settingState?.pinCode != null && Redux.store!.state.settingState!.pinCode!.length > 3;
    final bool pinLocked = Redux.store!.state.settingState?.pinLocked == true;
    final sp = await SharedPreferences.getInstance();
    sp.remove(backgroundedTimeKey);
    sp.setInt(lastKnownStateKey, AppLifecycleState.resumed.index);// previous state
    if ( pinIsExist == true && pinLocked == true ) {
      await Future.delayed(Duration(milliseconds: 50));
      pushToLockScreen();
    }
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    selectedTabIndex = 0;
    pageController = new PageController(initialPage: selectedTabIndex);
    Redux.store!.dispatch(checkSmena);
    _dataService.checkDbFill(Redux.store!.state.userState!.user!);
    _checkLockPin();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    print('state = $state');
    switch(state) {
      case AppLifecycleState.resumed:
        _resumed();
        break;
      case AppLifecycleState.paused:
        _paused();
        break;
      case AppLifecycleState.inactive:
        _inactive();
        break;
      default:
        break;
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    pageController.dispose();
    super.dispose();
  }

  void _onSelectChoice(Choice choice) async {
    if (choice.command == 'exit') {
      Dialogs.showLoadingDialog(context, _keyLoader);
      Response<dynamic> result = await _api.logout(Redux.store!.state.userState!.user!.token!);
      if(result.operation && result.status == 200) {
        Redux.store!.dispatch(logoutAction);
      }
      Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
    } else if (choice.command == 'infokkm') {
      _navigatorService.push(InfoKkmViewRoute);
    } else if (choice.command == 'settings') {
      _navigatorService.push(SettingsViewRoute);
    } else if (choice.command == 'print') {
      _navigatorService.push(SettingsPrinterRoute);
    } else if (choice.command == 'bank') {
      _navigatorService.push(BankViewRoute);
    } else if (choice.command == 'tap2phone') {
      _navigatorService.push(BankSettingViewRoute);
    } else if (choice.command == 'fortepos') {
      _navigatorService.push(ForteSettingViewRoute);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        titleSpacing: 5.0,
        title: HeaderTitle(),
        actions: <Widget>[
          PopupMenu(
            onSelectChoice: _onSelectChoice,
          )
        ],
        backgroundColor: fillColor,
      ),
      body:StoreConnector<AppState, SettingState>(
        converter: (store) => store.state.settingState!,
        builder: (context, vm) {
          return PageView(
            pageSnapping: true,
            onPageChanged: (index) {
              setState(() {
                selectedTabIndex = index;
              });
            },
            controller: pageController,
            children: <Widget>[
              vm.mode == SettingModeKassa ? KassaTab(0) : CalculatorTab(0),
              AdditionalTab(1),
            ],
          );
        }
      ),
      bottomNavigationBar: BottomBar(
        pageController: pageController,
        selectedTabIndex: selectedTabIndex,
      ),
    );
  }
}
