// Copyright 2020 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

/// Bridge between the [FilterPropertySheet] and a filter object that has a number of
/// properties by which it filters lists. The [sheetLayout] provides both the properties
/// to be displayed and edited and also a suggestion for their layout.
abstract class FilterPropertySource extends Listenable {
  /// The list of properties exposed by the filter for editing.
  List<FilterPropertyNode> get sheetLayout;
}

/// The base class for all elements in a [FilterPropertySheet]. Most of the nodes will
/// be value properties, but some may be layout nodes.
///
/// @see [ValueFilterProperty], [FilterPropertyGroup]
abstract class FilterPropertyNode {
  /// The descriptive name of the property or layout group as will be displayed
  /// in the [FilterPropertySheet].
  String? get label;
}

/// The abstract base class of all valued properties, useful for both displaying them
/// in and editing them from a [FilterPropertySheet] and methods to make them useful
/// as the actual storage for the properties in a filter object. A filter object then
/// becomes mostly a list of these properties along with methods to combine them into
/// predicates for filtering data in a dashboard or other list.
///
/// @see [RegExpFilterProperty], [BoolFilterProperty]
abstract class ValueFilterProperty<T> extends ValueListenable<T> with FilterPropertyNode {
  ValueFilterProperty({required this.fieldName, this.label});

  /// The name of the field represented by this property, used to import and export
  /// the property values via maps.
  final String fieldName;

  @override
  final String? label;

  /// The value of the property converted to a [String] useful for importing and
  /// exporting the values via maps and JSON files.
  String get stringValue;
  set stringValue(String newValue);

  /// Whether the property is set to its default value.
  bool get isDefault;

  /// Resets this property to its default value;
  void reset();

  List<VoidCallback>? _listeners;

  @override
  void addListener(VoidCallback listener) {
    _listeners ??= <VoidCallback>[];
    _listeners!.add(listener);
  }

  @override
  void removeListener(VoidCallback listener) {
    _listeners?.remove(listener);
  }

  /// Notify all listeners that the value of the property has changed.
  void notifyListeners() {
    if (_listeners != null) {
      for (final VoidCallback listener in _listeners!) {
        listener();
      }
    }
  }
}

/// A class used to represent a Regular Expression property in the filter object.
class RegExpFilterProperty extends ValueFilterProperty<String?> {
  RegExpFilterProperty({required String fieldName, String? label, String? value, bool caseSensitive = true})
      : _value = value,
        _caseSensitive = caseSensitive,
        super(fieldName: fieldName, label: label);

  String? _value;
  final bool _caseSensitive;
  @override
  String? get value => _value;
  set value(String? newValue) {
    if (newValue == '') {
      newValue = null;
    }
    if (_value != newValue) {
      _value = newValue;
      _regExp = null;
      notifyListeners();
    }
    newValue ??= '';
    if (_controller != null && _controller!.text != newValue) {
      _controller!.text = newValue;
      // The listener callback should nop
    }
  }

  TextEditingController? _controller;
  TextEditingController? get controller {
    if (_controller == null) {
      _controller = TextEditingController(text: stringValue);
      _controller!.addListener(() {
        value = _controller!.text;
      });
    }
    return _controller;
  }

  @override
  String get stringValue => _value ?? '';

  @override
  set stringValue(String newValue) => value = newValue;

  @override
  bool get isDefault => _value == null;

  @override
  void reset() => value = null;

  /// The value of this property as a [RegExp] object, useful for matching its pattern
  /// against candidate values in the list being filtered.
  RegExp? _regExp;
  RegExp? get regExp => _regExp ??= _value == null ? null : RegExp(_value!, caseSensitive: _caseSensitive);
  set regExp(RegExp? newRegExp) => value = newRegExp == null || newRegExp.pattern == '' ? null : newRegExp.pattern;

  /// True iff the value, interpreted as a regular expression, matches the candidate [String].
  bool matches(String candidate) => regExp?.hasMatch(candidate) ?? true;
}

/// A class used to represent a boolean property in the filter object.
class BoolFilterProperty extends ValueFilterProperty<bool?> {
  BoolFilterProperty({required String fieldName, String? label, bool value = true})
      : _value = value,
        _defaultValue = value,
        super(fieldName: fieldName, label: label);

  bool? _value;
  final bool? _defaultValue;

  @override
  bool? get value => _value;
  set value(bool? newValue) {
    if (_value != newValue) {
      _value = newValue;
      notifyListeners();
    }
  }

  @override
  String get stringValue => _value.toString();

  @override
  set stringValue(String newValue) {
    if (newValue == 'true' || newValue == 't') {
      value = true;
    } else if (newValue == 'false' || newValue == 'f') {
      value = false;
    } else {
      throw 'Unrecognized bool value: $newValue';
    }
  }

  @override
  bool get isDefault => value == _defaultValue;

  @override
  void reset() => value = _defaultValue;
}

/// A class used to enclose a group of other [BoolFilterProperty] properties to be
/// presented in a more compact format in the property sheet.
class BoolFilterPropertyGroup extends FilterPropertyNode {
  BoolFilterPropertyGroup({this.label, this.members});

  @override
  final String? label;

  /// The boolean property members of this group.
  final List<BoolFilterProperty>? members;
}

/// A [Widget] used to display the values of the properties of a filter object and to allow
/// a user to edit those properties. The changes are recorded in new filter objects using the
/// [FilterPropertySource.copyWithMap] method and communicated back to the app live via
/// modifying the value of the [filterNotifier].
///
/// If an optional [onClose] callback is supplied, this sheet will include its own close control
/// and notify the creator when it is closed via the callback. Otherwise the creator is
/// responsible for the lifecycle of this sheet.
class FilterPropertySheet extends StatefulWidget {
  const FilterPropertySheet(this.propertySource, {this.onClose, Key? key}) : super(key: key);

  /// The notifier object used to get the initial value of the filter properties and to
  /// send back new filter objects with modified values as the user edits the fields.
  final FilterPropertySource? propertySource;

  /// The optional callback for when the close field on the sheet is used to close the
  /// sheet. This [Widget] will only implement its own close box if this callback is non-null.
  final Function()? onClose;

  @override
  State createState() => FilterPropertySheetState();
}

class FilterPropertySheetState extends State<FilterPropertySheet> {
  @override
  void initState() {
    super.initState();

    widget.propertySource!.addListener(_update);
  }

  @override
  void dispose() {
    widget.propertySource!.removeListener(_update);

    super.dispose();
  }

  static const TextStyle _labelStyle = TextStyle(
    fontSize: 16.0,
    fontWeight: FontWeight.normal,
    fontStyle: FontStyle.normal,
    decoration: TextDecoration.none,
  );

  void _update() {
    setState(() {});
  }

  Widget _pad(Widget child, Alignment alignment) {
    return Container(
      padding: const EdgeInsets.all(5.0),
      child: child,
      alignment: alignment,
    );
  }

  TableRow _makeRow(String label, Widget editable) {
    return TableRow(
      children: <Widget>[
        _pad(Text(label, style: _labelStyle), Alignment.centerRight),
        _pad(editable, Alignment.centerLeft),
      ],
    );
  }

  TableRow _makeTextFilterRow(RegExpFilterProperty property) {
    return _makeRow(
      property.label!,
      TextField(
        autofocus: true,
        controller: property.controller,
        decoration: const InputDecoration(
          hintText: '(JavaScript regular expression)',
        ),
        onChanged: (String value) => property.value = value,
      ),
    );
  }

  TableRow _makeBoolRow(BoolFilterProperty property) {
    return _makeRow(
      property.label!,
      Checkbox(
        value: property.value,
        onChanged: (bool? newValue) => property.value = newValue,
      ),
    );
  }

  Widget _makeLoneCheckbox(BoolFilterProperty property) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Text(property.label!, style: _labelStyle),
        Checkbox(
          value: property.value,
          onChanged: (bool? newValue) => property.value = newValue,
        ),
      ],
    );
  }

  TableRow _makeTableRow(FilterPropertyNode property) {
    if (property is RegExpFilterProperty) {
      return _makeTextFilterRow(property);
    }
    if (property is BoolFilterProperty) {
      return _makeBoolRow(property);
    }
    if (property is BoolFilterPropertyGroup) {
      return _makeRow(
        property.label!,
        Wrap(
          children: property.members!.map<Widget>(_makeLoneCheckbox).toList(),
        ),
      );
    }
    throw 'unrecognized FilterProperty: $property';
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        if (widget.onClose != null)
          Positioned(
            child: TextButton(
              child: const Icon(Icons.close),
              onPressed: widget.onClose,
            ),
          ),
        Table(
          defaultVerticalAlignment: TableCellVerticalAlignment.middle,
          columnWidths: const <int, TableColumnWidth>{
            0: IntrinsicColumnWidth(),
            1: FixedColumnWidth(300.0),
          },
          children: widget.propertySource!.sheetLayout.map(_makeTableRow).toList(),
        ),
      ],
    );
  }
}
