import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/helpers/server_config_helper.dart';
import 'package:comunic/helpers/settings_helper.dart';
import 'package:comunic/models/data_conservation_policy_settings.dart';
import 'package:comunic/models/server_config.dart';
import 'package:comunic/ui/dialogs/input_user_password_dialog.dart';
import 'package:comunic/ui/dialogs/multi_choices_dialog.dart';
import 'package:comunic/ui/widgets/async_screen_widget.dart';
import 'package:comunic/ui/widgets/settings/header_spacer_section.dart';
import 'package:comunic/ui/widgets/settings/multi_choices_settings_tile.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:settings_ui/settings_ui.dart';

/// Account privacy settings
///
/// @author Pierre HUBERT

class AccountPrivacySettings extends StatefulWidget {
  @override
  _AccountPrivacySettingsState createState() => _AccountPrivacySettingsState();
}

class _AccountPrivacySettingsState extends State<AccountPrivacySettings> {
  final _key = GlobalKey<AsyncScreenWidgetState>();
  ServerConfig _serverConfig;
  DataConservationPolicySettings _userSettings;
  String _cachedPassword;

  Future<void> _loadSettings() async {
    _serverConfig = ServerConfigurationHelper.config;
    _userSettings = await SettingsHelper.getDataConservationPolicy();
  }

  @override
  Widget build(BuildContext context) {
    return AsyncScreenWidget(
      key: _key,
      onReload: _loadSettings,
      onBuild: () => SettingsList(sections: [
        HeadSpacerSection(),
        SettingsSection(
          title: tr("Data conservation policy"),
          tiles: _dataConservationPolicyTiles,
        ),
        HeadSpacerSection(),
        HeadSpacerSection(),
        SettingsSection(title: tr("Danger zone"), tiles: [
          SettingsTile(
            title: tr("Delete your account"),
            subtitle: tr(
                "Permanently delete your account and all data related to it."),
            onPressed: (_) => _deleteAccount(),
          )
        ])
      ]),
      errorMessage: tr("Failed to load privacy settings!"),
    );
  }

  List<SettingsTile> get _dataConservationPolicyTiles => [
        DataConservationPolicyTile(
          value: _userSettings.notificationLifetime,
          title: tr("Automatically delete unread notifications after"),
          onChange: (val) {
            _userSettings.notificationLifetime = val;
            _updateDataConservationPolicy();
          },
          minValue:
              _serverConfig.dataConservationPolicy.minNotificationLifetime,
        ),
        DataConservationPolicyTile(
          value: _userSettings.commentsLifetime,
          title: tr("Automatically delete your comments after"),
          onChange: (val) {
            _userSettings.commentsLifetime = val;
            _updateDataConservationPolicy();
          },
          minValue: _serverConfig.dataConservationPolicy.minCommentsLifetime,
        ),
        DataConservationPolicyTile(
          value: _userSettings.postsLifetime,
          title: tr("Automatically delete your posts after"),
          onChange: (val) {
            _userSettings.postsLifetime = val;
            _updateDataConservationPolicy();
          },
          minValue: _serverConfig.dataConservationPolicy.minPostsLifetime,
        ),
        DataConservationPolicyTile(
          value: _userSettings.conversationMessagesLifetime,
          title: tr("Automatically delete your conversation messages after"),
          onChange: (val) {
            _userSettings.conversationMessagesLifetime = val;
            _updateDataConservationPolicy();
          },
          minValue: _serverConfig
              .dataConservationPolicy.minConversationMessagesLifetime,
        ),
        DataConservationPolicyTile(
          value: _userSettings.likesLifetime,
          title: tr("Automatically delete your likes after"),
          onChange: (val) {
            _userSettings.likesLifetime = val;
            _updateDataConservationPolicy();
          },
          minValue: _serverConfig.dataConservationPolicy.minLikesLifetime,
        ),
        DataConservationPolicyTile(
          value: _userSettings.inactiveAccountLifeTime,
          title: tr(
              "Automatically delete your account if you have been inactive for"),
          onChange: (val) {
            _userSettings.inactiveAccountLifeTime = val;
            _updateDataConservationPolicy();
          },
          minValue:
              _serverConfig.dataConservationPolicy.minInactiveAccountLifetime,
        ),
      ];

  void _updateDataConservationPolicy() async {
    try {
      if (_cachedPassword == null)
        _cachedPassword = await showUserPasswordDialog(context);

      await SettingsHelper.setDataConservationPolicy(
          _cachedPassword, _userSettings);

      _key.currentState.refresh();
    } catch (e, s) {
      print("Could not update data conservation policy! $e\n$s");
      showSimpleSnack(
          context, tr("Failed to update data conservation policy!"));
    }
  }

  /// Permanently delete user account
  void _deleteAccount() async {
    try {
      // First dialog
      if (!await showConfirmDialog(
          context: context,
          message: tr(
              "Do you really want to delete your account? This operation CAN NOT be reverted!")))
        return;

      // Ask user password dialog
      final password = await showUserPasswordDialog(context);
      if (password == null) return;

      // Last chance dialog
      if (await showCupertinoDialog<bool>(
              context: context,
              builder: (c) => _LastChanceDeleteAccountDialog()) !=
          true) return;

      // Delete account
      await AccountHelper.deleteAccount(password);
    } catch (e, stack) {
      print("Could not delete user account! $e\n$stack");
      showSimpleSnack(context, tr("Could not delete your account!"));
    }
  }
}

class DataConservationPolicyTile extends SettingsTile {
  final int value;
  final String title;
  final Function(int) onChange;
  final int minValue;

  const DataConservationPolicyTile({
    @required this.value,
    @required this.title,
    @required this.onChange,
    @required this.minValue,
  })  : assert(title != null),
        assert(onChange != null),
        assert(minValue != null);

  @override
  Widget build(BuildContext context) {
    return MultiChoicesSettingsTile(
      title: title,
      choices: _choices,
      currentValue: _roundValue,
      onChanged: onChange,
    );
  }

  int get _day => 60 * 60 * 24;

  int get _month => _day * 30;

  int get _year => _day * 365;

  int get _roundValue {
    if (this.value == null) return 0;

    return _choices.firstWhere((element) => element.id >= this.value).id;
  }

  List<MultiChoiceEntry<int>> get _choices => [
        MultiChoiceEntry(id: 0, title: tr("Never"), hidden: false),
        MultiChoiceEntry(
          id: _day * 7,
          title: tr("7 days"),
          hidden: _day * 7 < minValue,
        ),
        MultiChoiceEntry(
          id: _day * 15,
          title: tr("15 days"),
          hidden: _day * 15 < minValue,
        ),
        MultiChoiceEntry(
          id: _month,
          title: tr("1 month"),
          hidden: _month < minValue,
        ),
        MultiChoiceEntry(
          id: _month * 3,
          title: tr("3 months"),
          hidden: _month * 3 < minValue,
        ),
        MultiChoiceEntry(
          id: _month * 6,
          title: tr("6 months"),
          hidden: _month * 6 < minValue,
        ),
        MultiChoiceEntry(
          id: _year,
          title: tr("1 year"),
          hidden: _year < minValue,
        ),
        MultiChoiceEntry(
          id: _year * 2,
          title: tr("2 years"),
          hidden: _year * 5 < minValue,
        ),
        MultiChoiceEntry(
          id: _year * 5,
          title: tr("5 years"),
          hidden: _year * 5 < minValue,
        ),
        MultiChoiceEntry(
          id: _year * 10,
          title: tr("10 years"),
          hidden: _year * 10 < minValue,
        ),
        MultiChoiceEntry(
          id: _year * 50,
          title: tr("50 years"),
          hidden: _year * 50 < minValue,
        ),
      ];
}

class _LastChanceDeleteAccountDialog extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoAlertDialog(
      title: Text(tr("Delete your account")),
      content: Text(tr(
          "Let us ask you one last time. Do you really want to delete your account? If you decide to do so, your data will be permanently removed from our servers, so we will not be able to recover your account. If you decide to proceed, the deletion process will start immediatly and you will automatically get disconnected from your account.")),
      actions: <Widget>[
        CupertinoDialogAction(
          isDefaultAction: true,
          child: Text(tr("Cancel")),
          onPressed: () => Navigator.of(context).pop(false),
        ),
        CupertinoDialogAction(
          isDestructiveAction: true,
          child: Text(tr("Confirm")),
          onPressed: () => Navigator.of(context).pop(true),
        ),
      ],
    );
  }
}