import 'package:comunic/helpers/groups_helper.dart';
import 'package:comunic/helpers/settings_helper.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

/// Show a dialog to offer the user to pick a virtual directory
///
/// @author Pierre HUBERT

enum VirtualDirectoryTargetType { USER, GROUP }

enum _CheckStatus { EMPTY, PENDING, VALID, INVALID }

Future<String> showVirtualDirectoryDialog({
  @required BuildContext context,
  @required String initialDirectory,
  @required int id,
  @required VirtualDirectoryTargetType type,
}) async {
  assert(context != null);
  assert(initialDirectory != null);
  assert(id != null);
  assert(type != null);

  return await showDialog<String>(
      context: context,
      builder: (c) => _VirtualDirectoryPicker(
          type: type, id: id, initialDirectory: initialDirectory));
}

class _VirtualDirectoryPicker extends StatefulWidget {
  final String initialDirectory;
  final int id;
  final VirtualDirectoryTargetType type;

  const _VirtualDirectoryPicker({
    Key key,
    @required this.initialDirectory,
    @required this.id,
    @required this.type,
  })  : assert(initialDirectory != null),
        assert(id != null),
        assert(type != null),
        super(key: key);

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

class __VirtualDirectoryPickerState extends SafeState<_VirtualDirectoryPicker> {
  TextEditingController _controller;
  var _status = _CheckStatus.VALID;

  String get _currentValue => _controller.text;

  @override
  void initState() {
    super.initState();
    _controller = TextEditingController(text: widget.initialDirectory);
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text(tr("Choose a virtual directory")),

      // Dialog content
      content: TextField(
        controller: _controller,
        onChanged: (s) => _checkValue(),
        decoration: InputDecoration(
          alignLabelWithHint: true,
          labelText: tr("Virtual directory"),
          helperText: _status == _CheckStatus.PENDING
              ? tr("Checking availability...")
              : (_status == _CheckStatus.VALID
                  ? tr("You can use this virtual directory.")
                  : null),
          errorText: _status == _CheckStatus.INVALID
              ? tr("This virtual directory is invalid / unvailable !")
              : null,
        ),
      ),

      // Dialog action
      actions: <Widget>[
        // Cancel
        MaterialButton(
          onPressed: () => Navigator.of(context).pop(),
          child: Text(tr("Cancel").toUpperCase()),
        ),

        // Confirm
        MaterialButton(
          onPressed:
              _status == _CheckStatus.VALID || _status == _CheckStatus.EMPTY
                  ? () => Navigator.of(context).pop(_currentValue)
                  : null,
          child: Text(tr("Confirm").toUpperCase()),
        ),
      ],
    );
  }

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

  /// Check new given value
  void _checkValue() async {
    final value = _currentValue;
    try {
      _setStatus(_CheckStatus.PENDING);

      if (value.length == 0) {
        _setStatus(_CheckStatus.EMPTY);
        return;
      }

      // Validate directory. This will throw in case of failure
      switch (widget.type) {
        case VirtualDirectoryTargetType.USER:
          await SettingsHelper.checkUserDirectoryAvailability(value);
          break;

        case VirtualDirectoryTargetType.GROUP:
          await GroupsHelper.checkVirtualDirectoryAvailability(
              widget.id, value);
          break;
      }

      if (_currentValue == value) {
        _setStatus(_CheckStatus.VALID);
      }
    } catch (e, stack) {
      if (_currentValue == value) {
        print("Could not validate given directory! $e\n$stack");
        _setStatus(_CheckStatus.INVALID);
      }
    }
  }
}