import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/models/res_check_password_reset_token.dart';
import 'package:comunic/ui/dialogs/input_new_password_dialog.dart';
import 'package:comunic/ui/widgets/async_screen_widget.dart';
import 'package:comunic/ui/widgets/new_password_input_widget.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';

/// Reset user password route
///
/// @author Pierre HUBERT

class PasswordResetRoute extends StatelessWidget {
  final String token;

  const PasswordResetRoute({
    Key key,
    @required this.token,
  })  : assert(token != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(tr("Change your password")),
      ),
      body: _PasswordResetBody(token: token),
    );
  }
}

class _PasswordResetBody extends StatefulWidget {
  final String token;

  const _PasswordResetBody({Key key, @required this.token})
      : assert(token != null),
        super(key: key);

  @override
  __PasswordResetBodyState createState() => __PasswordResetBodyState();
}

enum _Status { BEFORE_CHANGE, WHILE_CHANGE, AFTER_CHANGE }

class __PasswordResetBodyState extends SafeState<_PasswordResetBody> {
  final _key = GlobalKey<AsyncScreenWidgetState>();

  var _status = _Status.BEFORE_CHANGE;
  ResCheckPasswordToken _tokenInfo;

  void _setStatus(_Status s) => setState(() => _status = s);

  Future<void> _validateToken() async {
    _status = _Status.BEFORE_CHANGE;
    _tokenInfo = await AccountHelper.validatePasswordResetToken(widget.token);
  }

  @override
  Widget build(BuildContext context) {
    return AsyncScreenWidget(
      key: _key,
      onReload: _validateToken, // The first time, we validate the token
      onBuild: _buildBody,
      errorMessage: tr(
          "Could not validate your password reset token! Maybe it has expired now..."),
    );
  }

  Widget _buildBody() {
    // The user has not requested yet to change his password
    if (_status == _Status.BEFORE_CHANGE)
      return Center(
          child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text(tr("You can choose a new password.")),
          OutlineButton(
            onPressed: _changePassword,
            child: Text(tr("Choose a new password")),
          )
        ],
      ));

    // Password is being changed
    if (_status == _Status.WHILE_CHANGE) return buildCenteredProgressBar();

    // Password was successfully changed!
    if (_status == _Status.AFTER_CHANGE)
      return Center(
          child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text(
            tr("Congratulations! Your password has now been successfully changed!"),
            textAlign: TextAlign.center,
          ),
          OutlineButton(
            onPressed: _quitScreen,
            child: Text(tr("Login")),
          )
        ],
      ));

    throw Exception("Unreachable statement!");
  }

  /// Ask the user to specify his new password
  void _changePassword() async {
    try {
      // Ask for new password
      final newPass = await showInputNewPassword(
        context: context,
        userInfo: UserInfoForPassword(
          firstName: _tokenInfo.firstName,
          lastName: _tokenInfo.lastName,
          email: _tokenInfo.email,
        ),
      );
      if (newPass == null) return;
      _setStatus(_Status.WHILE_CHANGE);

      // Apply it
      await AccountHelper.changeAccountPassword(widget.token, newPass);
      _setStatus(_Status.AFTER_CHANGE);
    } catch (e, s) {
      print("Could not change user password! $e\n$s");
      showSimpleSnack(context, tr("Could not change your password!"));

      // We start everything again
      _key.currentState.refresh();
    }
  }

  /// Go back to login screen
  void _quitScreen() => Navigator.of(context).pop();
}