import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';

typedef ChipBuilder<T> = Widget Function(BuildContext context, T chip);
typedef OnChipAdded<T> = void Function(T chip);
typedef OnChipRemoved<T> = void Function(T chip);

class ChipsInputTextField<T> extends StatefulWidget {
  final TextEditingController controller;
  final FocusNode focusNode;
  final ValueChanged<String> onInputChanged;
  final ChipBuilder<T> chipBuilder;
  final OnChipAdded<T> onChipAdded;
  final OnChipRemoved<T> onChipRemoved;
  final String hint;

  const ChipsInputTextField({
    Key key,
    @required this.chipBuilder,
    @required this.controller,
    this.onInputChanged,
    this.focusNode,
    this.onChipAdded,
    this.onChipRemoved,
    this.hint = 'Type a name',
  }) : super(key: key);

  @override
  ChipInputTextFieldState<T> createState() => ChipInputTextFieldState<T>();
}

class ChipInputTextFieldState<T> extends State<ChipsInputTextField<T>> {
  final _chips = <T>{};
  bool _pauseItemAddition = false;

  void addItem(T item) {
    setState(() => _chips.add(item));
    if (widget.onChipAdded != null) widget.onChipAdded(item);
  }

  void removeItem(T item) {
    setState(() {
      _chips.remove(item);
      if (_chips.isEmpty) resumeItemAddition();
    });
    if (widget.onChipRemoved != null) widget.onChipRemoved(item);
  }

  void pauseItemAddition() {
    if (!_pauseItemAddition) {
      setState(() => _pauseItemAddition = true);
    }
    widget.focusNode?.unfocus();
  }

  void resumeItemAddition() {
    if (_pauseItemAddition) {
      setState(() => _pauseItemAddition = false);
    }
    widget.focusNode?.requestFocus();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _pauseItemAddition ? resumeItemAddition : null,
      child: Material(
        elevation: 1,
        color: StreamChatTheme.of(context).colorTheme.white,
        child: Container(
          child: Padding(
            padding: const EdgeInsets.fromLTRB(16, 16, 16, 16),
            child: IntrinsicHeight(
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.baseline,
                children: [
                  Padding(
                    padding: const EdgeInsets.symmetric(vertical: 4.0),
                    child: Text(
                      'TO:',
                      style: StreamChatTheme.of(context)
                          .textTheme
                          .footnote
                          .copyWith(
                              color: StreamChatTheme.of(context)
                                  .colorTheme
                                  .black
                                  .withOpacity(.5)),
                    ),
                  ),
                  SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Wrap(
                          spacing: 8.0,
                          runSpacing: 4.0,
                          children: _chips.map((item) {
                            return widget.chipBuilder(context, item);
                          }).toList(),
                        ),
                        if (!_pauseItemAddition)
                          TextField(
                            controller: widget.controller,
                            onChanged: widget.onInputChanged,
                            focusNode: widget.focusNode,
                            decoration: InputDecoration(
                              isDense: true,
                              border: InputBorder.none,
                              focusedBorder: InputBorder.none,
                              enabledBorder: InputBorder.none,
                              errorBorder: InputBorder.none,
                              disabledBorder: InputBorder.none,
                              contentPadding: const EdgeInsets.only(top: 4.0),
                              hintText: widget.hint,
                              hintStyle: StreamChatTheme.of(context)
                                  .textTheme
                                  .body
                                  .copyWith(
                                      color: StreamChatTheme.of(context)
                                          .colorTheme
                                          .black
                                          .withOpacity(.5)),
                            ),
                          ),
                      ],
                    ),
                  ),
                  SizedBox(width: 12),
                  Align(
                    alignment: Alignment.bottomCenter,
                    child: IconButton(
                      icon: _chips.isEmpty
                          ? StreamSvgIcon.user(
                              color: StreamChatTheme.of(context)
                                  .colorTheme
                                  .black
                                  .withOpacity(0.5),
                              size: 24,
                            )
                          : StreamSvgIcon.userAdd(
                              color: StreamChatTheme.of(context)
                                  .colorTheme
                                  .black
                                  .withOpacity(0.5),
                              size: 24,
                            ),
                      onPressed: resumeItemAddition,
                      alignment: Alignment.topRight,
                      visualDensity: VisualDensity.compact,
                      padding: const EdgeInsets.all(0),
                      splashRadius: 24,
                      constraints: BoxConstraints.tightFor(
                        height: 24,
                        width: 24,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
