import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_quill/widgets/controller.dart';
import 'package:flutter_quill/widgets/delegate.dart';
import 'package:flutter_quill/widgets/editor.dart';

class QuillField extends StatefulWidget {
  final QuillController controller;
  final FocusNode focusNode;
  final ScrollController scrollController;
  final bool scrollable;
  final EdgeInsetsGeometry padding;
  final bool autofocus;
  final bool showCursor;
  final bool readOnly;
  final bool enableInteractiveSelection;
  final double minHeight;
  final double maxHeight;
  final bool expands;
  final TextCapitalization textCapitalization;
  final Brightness keyboardAppearance;
  final ScrollPhysics scrollPhysics;
  final ValueChanged<String> onLaunchUrl;
  final InputDecoration decoration;
  final Widget toolbar;
  final EmbedBuilder embedBuilder;

  QuillField({
    Key key,
    @required this.controller,
    this.focusNode,
    this.scrollController,
    this.scrollable = true,
    this.padding = EdgeInsets.zero,
    this.autofocus = false,
    this.showCursor = true,
    this.readOnly = false,
    this.enableInteractiveSelection = true,
    this.minHeight,
    this.maxHeight,
    this.expands = false,
    this.textCapitalization = TextCapitalization.sentences,
    this.keyboardAppearance = Brightness.light,
    this.scrollPhysics,
    this.onLaunchUrl,
    this.decoration,
    this.toolbar,
    this.embedBuilder,
  }) : super(key: key);

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

class _QuillFieldState extends State<QuillField> {
  bool _focused;

  void _editorFocusChanged() {
    setState(() {
      _focused = widget.focusNode.hasFocus;
    });
  }

  @override
  void initState() {
    super.initState();
    _focused = widget.focusNode.hasFocus;
    widget.focusNode.addListener(_editorFocusChanged);
  }

  @override
  void didUpdateWidget(covariant QuillField oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.focusNode != oldWidget.focusNode) {
      oldWidget.focusNode.removeListener(_editorFocusChanged);
      widget.focusNode.addListener(_editorFocusChanged);
      _focused = widget.focusNode.hasFocus;
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget child = QuillEditor(
      controller: widget.controller,
      focusNode: widget.focusNode,
      scrollController: widget.scrollController,
      scrollable: widget.scrollable,
      padding: widget.padding,
      autoFocus: widget.autofocus,
      showCursor: widget.showCursor,
      readOnly: widget.readOnly,
      enableInteractiveSelection: widget.enableInteractiveSelection,
      minHeight: widget.minHeight,
      maxHeight: widget.maxHeight,
      expands: widget.expands,
      textCapitalization: widget.textCapitalization,
      keyboardAppearance: widget.keyboardAppearance,
      scrollPhysics: widget.scrollPhysics,
      onLaunchUrl: widget.onLaunchUrl,
      embedBuilder: widget.embedBuilder,
    );

    if (widget.toolbar != null) {
      child = Column(
        children: [
          child,
          Visibility(
            child: widget.toolbar,
            visible: _focused,
            maintainSize: true,
            maintainAnimation: true,
            maintainState: true,
          ),
        ],
      );
    }

    return AnimatedBuilder(
      animation:
          Listenable.merge(<Listenable>[widget.focusNode, widget.controller]),
      builder: (BuildContext context, Widget child) {
        return InputDecorator(
          decoration: _getEffectiveDecoration(),
          isFocused: widget.focusNode.hasFocus,
          // TODO: Document should be considered empty of it has single empty line with no styles applied
          isEmpty: widget.controller.document.length == 1,
          child: child,
        );
      },
      child: child,
    );
  }

  InputDecoration _getEffectiveDecoration() {
    return (widget.decoration ?? const InputDecoration())
        .applyDefaults(Theme.of(context).inputDecorationTheme)
        .copyWith(
          enabled: !widget.readOnly,
          hintMaxLines: widget.decoration?.hintMaxLines,
        );
  }
}