import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/helpers/events_helper.dart';
import 'package:comunic/helpers/server_config_helper.dart';
import 'package:comunic/helpers/version_helper.dart';
import 'package:comunic/helpers/websocket_helper.dart';
import 'package:comunic/ui/dialogs/deprecation_dialog.dart';
import 'package:comunic/ui/routes/login_route.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/routes/main_route/smartphone_route.dart';
import 'package:comunic/ui/routes/main_route/tablet_route.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/flutter_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';

/// Comunic account initialization widget
///
/// Application screens should only appears as children of this widget
///
/// This widget ensures that the application is correctly initialized before
/// starting it
///
/// @author Pierre Hubert

class InitializeWidget extends StatefulWidget {
  @override
  _InitializeWidgetState createState() => _InitializeWidgetState();
}

class _InitializeWidgetState extends SafeState<InitializeWidget> {
  bool _error = false;

  @override
  void initState() {
    _tryConnect();

    super.initState();

    // Check if login token are considered as invalid
    super.listen<InvalidLoginTokensEvent>((ev) => _openLoginPage());

    // Listen to WebSocket close event
    super.listen<WSClosedEvent>((e) {
      _popToMainRoute();
      _tryConnect();
    });
  }

  @override
  void dispose() {
    super.dispose();
    WebSocketHelper.close();
  }

  /// Open login page
  _openLoginPage() {
    Navigator.of(context)
        .pushReplacement(MaterialPageRoute(builder: (c) => LoginRoute()));
  }

  /// Try to connect to server
  void _tryConnect() async {
    try {
      await ServerConfigurationHelper.ensureLoaded();

      if (!isWeb &&
          ServerConfigurationHelper.config.minSupportedMobileVersion >
              VersionHelper.version) await showDeprecationDialog(context);

      if (!AccountHelper.isUserIDLoaded) {
        _popToMainRoute();
        _openLoginPage();
        return;
      }

      print("Attempting WebSocket connection...");

      setState(() {
        _error = false;
      });

      await WebSocketHelper.connect();

      setState(() {});
    } catch (e, stack) {
      print("Could not connect to server! $e");
      print(stack);

      _popToMainRoute();

      setState(() {
        _error = true;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return (!_error && WebSocketHelper.isConnected())
        ? (isTablet(context)
            ? TabletRoute(key: mainControllerKey)
            : SmartphoneMainRoute(key: mainControllerKey))
        : _buildNonReadyWidget();
  }

  /// Build loading widget
  Widget _buildNonReadyWidget() {
    return Scaffold(
      backgroundColor: Colors.indigo.shade900,
      body: Center(
        child: Material(
          color: Colors.transparent,
          textStyle: TextStyle(color: Colors.white),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Spacer(
                flex: 4,
              ),
              Text(
                tr("Comunic"),
                style: TextStyle(fontSize: 50),
              ),
              Spacer(
                flex: 2,
              ),
              _error ? _buildErrorWidget() : _buildConnectingWidget(),
              Spacer(
                flex: 2,
              ),
              !isWeb
                  ? Text(tr("Version %version% - Build %build%", args: {
                      "version": VersionHelper.info.version.toString(),
                      "build": VersionHelper.info.buildNumber.toString()
                    }))
                  : Container(),
              Spacer(flex: 1),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildConnectingWidget() {
    return CircularProgressIndicator();
  }

  Widget _buildErrorWidget() {
    return Column(
      children: <Widget>[
        Icon(Icons.error, color: Colors.white),
        SizedBox(height: 30),
        Text(tr("Could not connect to server!")),
        SizedBox(
          height: 30,
        ),
        ElevatedButton(
          onPressed: () => _tryConnect(),
          child: Text(tr("Try again")),
        ),
      ],
    );
  }

  void _popToMainRoute() {
    // Pop until we reach main route
    Navigator.of(context).popUntil((settings) =>
        ModalRoute.of(context).isCurrent || !ModalRoute.of(context).isActive);
  }
}