// 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 super.fieldName, super.label, String? value, bool caseSensitive = true})
      : _value = value,
        _caseSensitive = caseSensitive;

  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 super.fieldName, super.label, bool value = true})
      : _value = value,
        _defaultValue = value;

  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, super.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),
      alignment: alignment,
      child: child,
    );
  }

  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(
              onPressed: widget.onClose,
              child: const Icon(Icons.close),
            ),
          ),
        Table(
          defaultVerticalAlignment: TableCellVerticalAlignment.middle,
          columnWidths: const <int, TableColumnWidth>{
            0: IntrinsicColumnWidth(),
            1: FixedColumnWidth(300.0),
          },
          children: widget.propertySource!.sheetLayout.map(_makeTableRow).toList(),
        ),
      ],
    );
  }
}
