import 'package:flutter/material.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import '../../core/theme/app_colors_extension.dart';
import '../../core/i18n/app_localizations.dart';

/// 列表页筛选面板，从右侧滑出。
///
/// ## 调用方式
///
/// ```dart
/// // 1. 声明筛选值的 provider
/// final dateStart = ref.watch(expenseDateStartProvider);
/// final dateEnd   = ref.watch(expenseDateEndProvider);
///
/// // 2. 构建 FilterGroup 列表
/// final filterGroups = [
///   FilterGroup(
///     title: '日期范围',
///     type: FilterGroupType.dateRange,
///     sections: [
///       FilterSection(
///         label: '日期范围',
///         type: FilterSectionType.dateRange,
///         startDate: dateStart, endDate: dateEnd,
///         onStartChanged: (v) => ref.read(startProvider.notifier).state = v,
///         onEndChanged: (v) => ref.read(endProvider.notifier).state = v,
///       ),
///     ],
///   ),
/// ];
///
/// // 3. 维护辅助变量
/// final hasFilter     = ListFilterPanel.hasActiveFilter(filterGroups);
/// final filterVersion = Object.hash(dateStart, dateEnd);
/// void onReset() { /* 清空所有筛选 provider */ }
///
/// // 4. 调用 show + 更新 NavBarConfig
/// ListFilterPanel.show(context,
///   groups: filterGroups,
///   onReset: onReset,
///   onConfirm: () {},
///   defaultStartDate: DateTime(year, month, 1),
///   defaultEndDate: DateTime(year, month, day),
/// );
/// ```
///
/// ## 新增筛选条件
///
/// ① 声明 provider → ② 在 `filterGroups` 中加 `FilterSection`
/// → ③ 更新 `filterVersion = Object.hash(...)` 加入新值
/// → ④ 更新 `onReset` 清空新 provider
/// → ⑤ 列表请求逻辑接入新 provider。
///
/// `FilterSection.type` 支持 [FilterSectionType.dateRange]（日期）、
/// [FilterSectionType.singleSelect]（单选）、[FilterSectionType.multiSelect]（多选）。
class ListFilterPanel {
  ListFilterPanel._();

  static TDDrawer? _currentDrawer;

  /// 从右侧弹出筛选面板
  ///
  /// [defaultStartDate]/[defaultEndDate] 可选默认日期范围，
  /// 当 [FilterSection] 未提供日期值时作为初始值。
  static void show(
    BuildContext context, {
    required List<FilterGroup> groups,
    required VoidCallback onReset,
    required VoidCallback onConfirm,
    DateTime? defaultStartDate,
    DateTime? defaultEndDate,
  }) {
    _currentDrawer?.close();

    final drawer = TDDrawer(
      context,
      width: 300,
      placement: TDDrawerPlacement.right,
      closeOnOverlayClick: true,
      showOverlay: true,
      onClose: () {
        _currentDrawer = null;
      },
      contentWidget: _FilterPopup(
        groups: groups,
        onReset: onReset,
        onConfirm: onConfirm,
        defaultStartDate: defaultStartDate,
        defaultEndDate: defaultEndDate,
        onClose: () {
          _currentDrawer?.close();
          _currentDrawer = null;
        },
      ),
    );
    _currentDrawer = drawer;
    drawer.show();
  }

  /// 是否有筛选条件激活（给 NavBar 红点使用）
  static bool hasActiveFilter(List<FilterGroup> groups) {
    return groups.any((g) => g.summary.isNotEmpty);
  }
}

// ============================================
//  可变的筛选值（面板内持有的本地状态）
// ============================================

class _SectionValue {
  final String label;
  final FilterSectionType type;
  final List<FilterOption> options;
  final ValueChanged<String>? onChanged;
  final ValueChanged<List<String>>? onMultiChanged;
  final ValueChanged<DateTime?>? onStartChanged;
  final ValueChanged<DateTime?>? onEndChanged;

  DateTime? startDate;
  DateTime? endDate;
  String? selectedValue;
  List<String>? selectedValues;

  _SectionValue({
    required this.label,
    required this.type,
    required this.options,
    this.onChanged,
    this.onMultiChanged,
    this.onStartChanged,
    this.onEndChanged,
    this.startDate,
    this.endDate,
    this.selectedValue,
    this.selectedValues,
  });

  /// 将本地值回写到原始回调（包括 null/空值，用于清除筛选）
  void apply() {
    if (type == FilterSectionType.dateRange) {
      onStartChanged?.call(startDate);
      onEndChanged?.call(endDate);
    } else if (type == FilterSectionType.singleSelect) {
      onChanged?.call(selectedValue ?? '');
    } else if (type == FilterSectionType.multiSelect) {
      onMultiChanged?.call(selectedValues ?? []);
    }
  }

  /// 重置为初始状态
  void reset() {
    startDate = null;
    endDate = null;
    selectedValue = null;
    selectedValues = null;
  }
}

// ============================================
//  右侧弹出面板
// ============================================

class _FilterPopup extends StatefulWidget {
  final List<FilterGroup> groups;
  final VoidCallback onReset;
  final VoidCallback onConfirm;
  final VoidCallback? onClose;
  final DateTime? defaultStartDate;
  final DateTime? defaultEndDate;

  const _FilterPopup({
    required this.groups,
    required this.onReset,
    required this.onConfirm,
    this.onClose,
    this.defaultStartDate,
    this.defaultEndDate,
  });

  @override
  State<_FilterPopup> createState() => _FilterPopupState();
}

class _FilterPopupState extends State<_FilterPopup> {
  late final List<_SectionValue> _values;

  @override
  void initState() {
    super.initState();
    _values = [];
    for (final g in widget.groups) {
      for (final s in g.sections) {
        _values.add(
          _SectionValue(
            label: s.label,
            type: s.type,
            options: s.options,
            onChanged: s.onChanged,
            onMultiChanged: s.onMultiChanged,
            onStartChanged: s.onStartChanged,
            onEndChanged: s.onEndChanged,
            startDate: s.startDate ?? widget.defaultStartDate,
            endDate: s.endDate ?? widget.defaultEndDate,
            selectedValue: s.selectedValue,
            selectedValues: s.selectedValues,
          ),
        );
      }
    }
  }

  void _applyAll() {
    for (final v in _values) {
      v.apply();
    }
    final onClose = widget.onClose;
    if (onClose != null) {
      onClose();
    } else {
      Navigator.of(context).pop();
    }
    widget.onConfirm();
  }

  void _resetAll() {
    for (final v in _values) {
      v.reset();
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    return LayoutBuilder(
      builder: (context, constraints) => Container(
        color: TDTheme.of(context).bgColorContainer,
        child: SafeArea(
          child: SizedBox(
            height: constraints.maxHeight,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                // 标题栏
                Padding(
                  padding: const EdgeInsets.fromLTRB(16, 28, 16, 14),
                  child: Row(
                    children: [
                      Icon(TDIcons.filter, size: 20, color: colors.textPrimary),
                      const SizedBox(width: 8),
                      Expanded(
                        child: Text(
                          l10n.get('filterTitle'),
                          style: TextStyle(
                            fontSize: 18,
                            fontWeight: FontWeight.w600,
                            color: colors.textPrimary,
                          ),
                        ),
                      ),
                      GestureDetector(
                        onTap: () {
                          final onClose = widget.onClose;
                          if (onClose != null) {
                            onClose();
                          } else {
                            Navigator.pop(context);
                          }
                        },
                        child: Icon(
                          TDIcons.close,
                          size: 22,
                          color: colors.textSecondary,
                        ),
                      ),
                    ],
                  ),
                ),

                // 筛选项区域
                Expanded(
                  child: SingleChildScrollView(
                    child: Column(
                      children: [
                        for (final g in widget.groups)
                          _GroupSection(
                            group: g,
                            values: _valuesForGroup(g),
                            onValuesChanged: () => setState(() {}),
                          ),
                      ],
                    ),
                  ),
                ),

                // 底部按钮
                Padding(
                  padding: const EdgeInsets.fromLTRB(16, 12, 16, 16),
                  child: Row(
                    children: [
                      Expanded(
                        child: TDButton(
                          text: l10n.get('reset'),
                          size: TDButtonSize.medium,
                          type: TDButtonType.outline,
                          shape: TDButtonShape.rectangle,
                          theme: TDButtonTheme.defaultTheme,
                          style: TDButtonStyle(
                            frameColor: colors.textSecondary,
                            frameWidth: 1,
                            textColor: colors.textSecondary,
                            backgroundColor: Colors.transparent,
                          ),
                          onTap: _resetAll,
                        ),
                      ),
                      const SizedBox(width: 12),
                      Expanded(
                        child: TDButton(
                          text: l10n.get('confirm'),
                          size: TDButtonSize.medium,
                          type: TDButtonType.fill,
                          shape: TDButtonShape.rectangle,
                          theme: TDButtonTheme.primary,
                          style: TDButtonStyle(
                            backgroundColor: colors.primary,
                            textColor: colors.bgCard,
                          ),
                          onTap: _applyAll,
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  List<_SectionValue> _valuesForGroup(FilterGroup group) {
    return _values.where((v) {
      return group.sections.any((s) => s.label == v.label && s.type == v.type);
    }).toList();
  }
}

// ============================================
//  分组区块
// ============================================

class _GroupSection extends StatelessWidget {
  final FilterGroup group;
  final List<_SectionValue> values;
  final VoidCallback onValuesChanged;

  const _GroupSection({
    required this.group,
    required this.values,
    required this.onValuesChanged,
  });

  void _applyQuickDate(DateTime start, DateTime end) {
    for (final v in values) {
      if (v.type == FilterSectionType.dateRange) {
        v.startDate = start;
        v.endDate = end;
      }
    }
    onValuesChanged();
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    final isDateGroup = group.type == FilterGroupType.dateRange;
    final now = DateTime.now();
    final today = DateTime(now.year, now.month, now.day);
    final monthEnd = DateTime(today.year, today.month + 1, 0);
    final quarterEndMonth = ((today.month - 1) ~/ 3 + 1) * 3;
    final quarterEnd = DateTime(today.year, quarterEndMonth + 1, 0);
    final yearEnd = DateTime(today.year, 12, 31);
    final weekStart = today.subtract(Duration(days: today.weekday - 1));
    final weekEnd = today.add(
      Duration(days: DateTime.daysPerWeek - today.weekday),
    );
    final lastMonthStart = DateTime(today.year, today.month - 1, 1);
    final lastMonthEnd = DateTime(today.year, today.month, 0);
    final last3MonthsStart = DateTime(today.year, today.month - 3, today.day);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 20, 16, 4),
          child: Text(
            group.title,
            style: TextStyle(
              fontSize: 13,
              fontWeight: FontWeight.w500,
              color: colors.textPlaceholder,
            ),
          ),
        ),
        if (isDateGroup) ...[
          Padding(
            padding: const EdgeInsets.fromLTRB(16, 4, 16, 8),
            child: Wrap(
              spacing: 6,
              runSpacing: 6,
              children: [
                _QuickDateChip(
                  label: l10n.get('filterThisWeek'),
                  start: weekStart,
                  end: weekEnd,
                  onTap: (s, e) => _applyQuickDate(s, e),
                ),
                _QuickDateChip(
                  label: l10n.get('filterThisMonth'),
                  start: DateTime(today.year, today.month, 1),
                  end: monthEnd,
                  onTap: (s, e) => _applyQuickDate(s, e),
                ),
                _QuickDateChip(
                  label: l10n.get('filterThisQuarter'),
                  start: DateTime(
                    today.year,
                    ((today.month - 1) ~/ 3) * 3 + 1,
                    1,
                  ),
                  end: quarterEnd,
                  onTap: (s, e) => _applyQuickDate(s, e),
                ),
                _QuickDateChip(
                  label: l10n.get('filterThisYear'),
                  start: DateTime(today.year, 1, 1),
                  end: yearEnd,
                  onTap: (s, e) => _applyQuickDate(s, e),
                ),
                _QuickDateChip(
                  label: l10n.get('filterLastMonth'),
                  start: lastMonthStart,
                  end: lastMonthEnd,
                  onTap: (s, e) => _applyQuickDate(s, e),
                ),
                _QuickDateChip(
                  label: l10n.get('filterLast3Months'),
                  start: last3MonthsStart,
                  end: today,
                  onTap: (s, e) => _applyQuickDate(s, e),
                ),
                _QuickDateChip(
                  label: l10n.get('filter7Days'),
                  start: today.subtract(const Duration(days: 6)),
                  end: today,
                  onTap: (s, e) => _applyQuickDate(s, e),
                ),
                _QuickDateChip(
                  label: l10n.get('filter30Days'),
                  start: today.subtract(const Duration(days: 29)),
                  end: today,
                  onTap: (s, e) => _applyQuickDate(s, e),
                ),
              ],
            ),
          ),
          ...values
              .where((v) => v.type == FilterSectionType.dateRange)
              .expand(
                (v) => [
                  _DateRow(value: v, isStart: true, onChanged: onValuesChanged),
                  _DateRow(
                    value: v,
                    isStart: false,
                    onChanged: onValuesChanged,
                  ),
                ],
              ),
        ] else
          ...values.map(
            (v) => _FilterRow(value: v, onChanged: onValuesChanged),
          ),
        const SizedBox(height: 8),
      ],
    );
  }
}

class _QuickDateChip extends StatelessWidget {
  final String label;
  final DateTime start;
  final DateTime end;
  final void Function(DateTime start, DateTime end) onTap;

  const _QuickDateChip({
    required this.label,
    required this.start,
    required this.end,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return GestureDetector(
      onTap: () => onTap(start, end),
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
        decoration: BoxDecoration(
          border: Border.all(color: colors.border),
          borderRadius: BorderRadius.circular(14),
          color: Colors.transparent,
        ),
        child: Text(
          label,
          style: TextStyle(fontSize: 13, color: colors.textSecondary),
        ),
      ),
    );
  }
}

// ============================================
//  日期行
// ============================================

class _DateRow extends StatelessWidget {
  final _SectionValue value;
  final bool isStart;
  final VoidCallback onChanged;

  const _DateRow({
    required this.value,
    required this.isStart,
    required this.onChanged,
  });

  String _fmt(DateTime? dt) {
    if (dt == null) return '';
    return '${dt.year}-${dt.month.toString().padLeft(2, '0')}-${dt.day.toString().padLeft(2, '0')}';
  }

  Future<void> _pick(BuildContext context, bool isStart) async {
    final now = DateTime.now();
    final fallback = isStart ? DateTime(now.year, now.month, 1) : now;
    final initial = isStart
        ? (value.startDate ?? fallback)
        : (value.endDate ?? fallback);
    DateTime? picked;

    if (!context.mounted) return;
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final theme = Theme.of(context);
    final selectHighlight = Container(
      height: 40,
      decoration: BoxDecoration(
        color: colors.primary.withValues(alpha: 0.08),
        borderRadius: BorderRadius.all(Radius.circular(8)),
      ),
    );
    await showModalBottomSheet<void>(
      context: context,
      backgroundColor: Colors.transparent,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
      ),
      builder: (ctx) {
        return Theme(
          data: theme,
          child: TDDatePicker(
            title: isStart
                ? AppLocalizations.of(context).get('filterSelectStartDate')
                : AppLocalizations.of(context).get('filterSelectEndDate'),
            backgroundColor: colors.bgCard,
            customSelectWidget: selectHighlight,
            model: DatePickerModel(
              useYear: true,
              useMonth: true,
              useDay: true,
              useHour: false,
              useMinute: false,
              useSecond: false,
              useWeekDay: false,
              dateStart: [2020, 1, 1],
              dateEnd: [now.year + 1, 12, 31],
              dateInitial: [initial.year, initial.month, initial.day],
            ),
            onConfirm: (selected) {
              picked = DateTime(
                selected['year'] ?? initial.year,
                selected['month'] ?? initial.month,
                selected['day'] ?? initial.day,
              );
              Navigator.of(ctx).pop();
            },
            onCancel: (_) => Navigator.of(ctx).pop(),
          ),
        );
      },
    );

    if (picked != null && context.mounted) {
      final l10n = AppLocalizations.of(context);
      if (isStart && value.endDate != null && picked!.isAfter(value.endDate!)) {
        TDMessage.showMessage(
          context: context,
          content: l10n.get('filterDateStartAfterEnd'),
          icon: TDIcons.error_circle_filled,
          theme: MessageTheme.warning,
          duration: 3000,
        );
        return;
      }
      if (!isStart &&
          value.startDate != null &&
          picked!.isBefore(value.startDate!)) {
        TDMessage.showMessage(
          context: context,
          content: l10n.get('filterDateEndBeforeStart'),
          icon: TDIcons.error_circle_filled,
          theme: MessageTheme.warning,
          duration: 3000,
        );
        return;
      }
      if (isStart) {
        value.startDate = picked;
      } else {
        value.endDate = picked;
      }
      onChanged();
    }
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final date = isStart ? value.startDate : value.endDate;
    final icon = isStart ? TDIcons.calendar_1 : TDIcons.calendar_2;

    return GestureDetector(
      onTap: () => _pick(context, isStart),
      behavior: HitTestBehavior.opaque,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
        child: Row(
          children: [
            Icon(icon, size: 16, color: colors.textSecondary),
            const SizedBox(width: 8),
            Text(
              isStart
                  ? AppLocalizations.of(context).get('filterStartDate')
                  : AppLocalizations.of(context).get('filterEndDate'),
              style: TextStyle(fontSize: 14, color: colors.textSecondary),
            ),
            const Spacer(),
            SizedBox(
              width: 110,
              child: Align(
                alignment: Alignment.centerRight,
                child: Text(
                  _fmt(date),
                  style: TextStyle(fontSize: 14, color: colors.primary),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            ),
            const SizedBox(width: 4),
            Icon(
              TDIcons.chevron_right,
              size: 16,
              color: colors.textPlaceholder,
            ),
          ],
        ),
      ),
    );
  }
}

// ============================================
//  筛选项行（单选 / 多选）
// ============================================

class _FilterRow extends StatelessWidget {
  final _SectionValue value;
  final VoidCallback onChanged;

  const _FilterRow({required this.value, required this.onChanged});

  Future<void> _handleTap(BuildContext context) async {
    final options = value.options;
    if (options.isEmpty) return;

    final labels = options.map((o) => o.label).toList();
    final isMulti = value.type == FilterSectionType.multiSelect;

    List<int> initialIndexes = [];
    if (isMulti) {
      final selectedSet = Set<String>.from(value.selectedValues ?? const []);
      for (int i = 0; i < options.length; i++) {
        if (selectedSet.contains(options[i].value)) initialIndexes.add(i);
      }
    } else {
      final idx = value.selectedValue != null
          ? options.indexWhere((o) => o.value == value.selectedValue)
          : -1;
      if (idx >= 0) initialIndexes = [idx];
    }

    if (!context.mounted) return;
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final theme = Theme.of(context);
    final selectHighlight = Container(
      height: 40,
      decoration: BoxDecoration(
        color: colors.primary.withValues(alpha: 0.08),
        borderRadius: BorderRadius.all(Radius.circular(8)),
      ),
    );
    await showModalBottomSheet<void>(
      context: context,
      backgroundColor: Colors.transparent,
      builder: (ctx) => Theme(
        data: theme,
        child: TDMultiPicker(
          title: value.label,
          backgroundColor: colors.bgCard,
          customSelectWidget: selectHighlight,
          data: [labels],
          initialIndexes: initialIndexes.isNotEmpty ? initialIndexes : null,
          onConfirm: (selected) {
            if (isMulti) {
              final values = <String>[];
              for (final s in selected) {
                if (s is int && s >= 0 && s < options.length) {
                  values.add(options[s].value);
                }
              }
              value.selectedValues = values;
            } else {
              if (selected.isNotEmpty && selected[0] is int) {
                final idx = selected[0] as int;
                if (idx >= 0 && idx < options.length) {
                  value.selectedValue = options[idx].value;
                }
              }
            }
            Navigator.of(ctx).pop();
            onChanged();
          },
        ),
      ),
    );
  }

  String get _summary {
    switch (value.type) {
      case FilterSectionType.singleSelect:
        if (value.selectedValue == null || value.selectedValue!.isEmpty) {
          return '';
        }
        final opt = value.options.where((o) => o.value == value.selectedValue);
        return opt.isNotEmpty ? opt.first.label : '';
      case FilterSectionType.multiSelect:
        if (value.selectedValues == null || value.selectedValues!.isEmpty) {
          return '';
        }
        final labels = value.options
            .where((o) => value.selectedValues!.contains(o.value))
            .map((o) => o.label);
        return labels.join('、');
      default:
        return '';
    }
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final summary = _summary;
    return GestureDetector(
      onTap: () => _handleTap(context),
      behavior: HitTestBehavior.opaque,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
        child: Row(
          children: [
            Icon(TDIcons.filter_1, size: 16, color: colors.textSecondary),
            const SizedBox(width: 8),
            Text(
              value.label,
              style: TextStyle(fontSize: 14, color: colors.textSecondary),
            ),
            const Spacer(),
            SizedBox(
              width: 110,
              child: Align(
                alignment: Alignment.centerRight,
                child: Text(
                  summary,
                  style: TextStyle(fontSize: 14, color: colors.primary),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            ),
            const SizedBox(width: 4),
            Icon(
              TDIcons.chevron_right,
              size: 16,
              color: colors.textPlaceholder,
            ),
          ],
        ),
      ),
    );
  }
}

// ============================================
//  数据模型（API 不变）
// ============================================

enum FilterSectionType { dateRange, singleSelect, multiSelect }

enum FilterGroupType { dateRange, other }

class FilterSection {
  final String label;
  final FilterSectionType type;
  final List<FilterOption> options;
  final String? selectedValue;
  final List<String>? selectedValues;
  final ValueChanged<String>? onChanged;
  final ValueChanged<List<String>>? onMultiChanged;
  final DateTime? startDate;
  final DateTime? endDate;
  final ValueChanged<DateTime?>? onStartChanged;
  final ValueChanged<DateTime?>? onEndChanged;

  const FilterSection({
    required this.label,
    required this.type,
    this.options = const [],
    this.selectedValue,
    this.selectedValues,
    this.onChanged,
    this.onMultiChanged,
    this.startDate,
    this.endDate,
    this.onStartChanged,
    this.onEndChanged,
  });

  String get summary {
    switch (type) {
      case FilterSectionType.dateRange:
        return '';
      case FilterSectionType.singleSelect:
        if (selectedValue == null) return '';
        final opt = options.where((o) => o.value == selectedValue);
        return opt.isNotEmpty ? opt.first.label : '';
      case FilterSectionType.multiSelect:
        if (selectedValues == null || selectedValues!.isEmpty) return '';
        final labels = options
            .where((o) => selectedValues!.contains(o.value))
            .map((o) => o.label);
        return labels.join('、');
    }
  }
}

class FilterOption {
  final String value;
  final String label;

  const FilterOption({required this.value, required this.label});
}

class FilterGroup {
  final String title;
  final FilterGroupType type;
  final List<FilterSection> sections;

  const FilterGroup({
    required this.title,
    required this.type,
    required this.sections,
  });

  String get summary {
    final parts = <String>[];
    for (final s in sections) {
      if (s.type == FilterSectionType.dateRange) {
        if (s.startDate != null) {
          parts.add(
            '${s.startDate!.month}/${s.startDate!.day} ~ ${s.endDate != null ? "${s.endDate!.month}/${s.endDate!.day}" : "..."}',
          );
        }
      } else {
        final sSum = s.summary;
        if (sSum.isNotEmpty) parts.add(sSum);
      }
    }
    return parts.join(' ');
  }
}
