import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:mobile_nebula/components/SpecialTextField.dart';
//TODO: reset doesn't update the ui but clears the field

class PlatformTextFormField extends FormField<String> {
  //TODO: auto-validate, enabled?
  PlatformTextFormField(
      {Key? key,
      widgetKey,
      this.controller,
      focusNode,
      nextFocusNode,
      TextInputType? keyboardType,
      textInputAction,
      List<TextInputFormatter>? inputFormatters,
      textAlign,
      autofocus,
      maxLines = 1,
      maxLength,
      maxLengthEnforcement,
      onChanged,
      keyboardAppearance,
      minLines,
      expands,
      suffix,
      textAlignVertical,
      String? initialValue,
      String? placeholder,
      FormFieldValidator<String>? validator,
      ValueChanged<String?>? onSaved})
      : super(
            key: key,
            initialValue: controller != null ? controller.text : (initialValue ?? ''),
            onSaved: onSaved,
            validator: (str) {
              if (validator != null) {
                return validator(str);
              }

              return null;
            },
            builder: (FormFieldState<String> field) {
              final _PlatformTextFormFieldState state = field as _PlatformTextFormFieldState;

              void onChangedHandler(String value) {
                if (onChanged != null) {
                  onChanged(value);
                }
                field.didChange(value);
              }

              return Column(crossAxisAlignment: CrossAxisAlignment.end, children: <Widget>[
                SpecialTextField(
                    key: widgetKey,
                    controller: state._effectiveController,
                    focusNode: focusNode,
                    nextFocusNode: nextFocusNode,
                    keyboardType: keyboardType,
                    textInputAction: textInputAction,
                    textAlign: textAlign,
                    autofocus: autofocus,
                    maxLines: maxLines,
                    maxLength: maxLength,
                    maxLengthEnforcement: maxLengthEnforcement,
                    onChanged: onChangedHandler,
                    keyboardAppearance: keyboardAppearance,
                    minLines: minLines,
                    expands: expands,
                    textAlignVertical: textAlignVertical,
                    placeholder: placeholder,
                    inputFormatters: inputFormatters,
                    suffix: suffix),
                field.hasError
                    ? Text(
                        field.errorText!,
                        style: TextStyle(color: CupertinoColors.systemRed.resolveFrom(field.context), fontSize: 13),
                        textAlign: textAlign,
                      )
                    : Container(height: 0)
              ]);
            });

  final TextEditingController? controller;

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

class _PlatformTextFormFieldState extends FormFieldState<String> {
  TextEditingController? _controller;

  TextEditingController get _effectiveController => widget.controller ?? _controller!;

  @override
  PlatformTextFormField get widget => super.widget as PlatformTextFormField;

  @override
  void initState() {
    super.initState();
    if (widget.controller == null) {
      _controller = TextEditingController(text: widget.initialValue);
    } else {
      widget.controller!.addListener(_handleControllerChanged);
    }
  }

  @override
  void didUpdateWidget(PlatformTextFormField oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.controller != oldWidget.controller) {
      oldWidget.controller?.removeListener(_handleControllerChanged);
      widget.controller?.addListener(_handleControllerChanged);

      if (oldWidget.controller != null && widget.controller == null)
        _controller = TextEditingController.fromValue(oldWidget.controller!.value);
      if (widget.controller != null) {
        setValue(widget.controller!.text);
        if (oldWidget.controller == null) _controller = null;
      }
    }
  }

  @override
  void dispose() {
    widget.controller?.removeListener(_handleControllerChanged);
    super.dispose();
  }

  @override
  void reset() {
    super.reset();
    setState(() {
      _effectiveController.text = widget.initialValue ?? "";
    });
  }

  void _handleControllerChanged() {
    // Suppress changes that originated from within this class.
    //
    // In the case where a controller has been passed in to this widget, we
    // register this change listener. In these cases, we'll also receive change
    // notifications for changes originating from within this class -- for
    // example, the reset() method. In such cases, the FormField value will
    // already have been set.
    if (_effectiveController.text != value) didChange(_effectiveController.text);
  }
}