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

/// 分页数据加载函数签名。
typedef PickerLoader<T> = Future<List<T>> Function(String keyword, int page);

/// 单选弹窗，返回选中项或 null。
Future<T?> showSearchablePicker<T>(
  BuildContext context, {
  required String title,
  required PickerLoader<T> loader,
  required String Function(T item) labelBuilder,
  String Function(T item)? subtitleBuilder,
  T? initialSelected,
  String? searchHint,
  VoidCallback? onRefresh,
}) {
  return Navigator.push<T>(
    context,
    TDSlidePopupRoute<T>(
      slideTransitionFrom: SlideTransitionFrom.bottom,
      isDismissible: true,
      builder: (_) => _SearchablePickerSheet<T>(
        title: title,
        multiSelect: false,
        loader: loader,
        labelBuilder: labelBuilder,
        subtitleBuilder: subtitleBuilder,
        initialSelected: initialSelected != null ? [initialSelected] : null,
        searchHint: searchHint,
        onRefresh: onRefresh,
      ),
    ),
  );
}

/// 多选弹窗，返回选中列表。
Future<List<T>> showSearchableMultiPicker<T>(
  BuildContext context, {
  required String title,
  required PickerLoader<T> loader,
  required String Function(T item) labelBuilder,
  String Function(T item)? subtitleBuilder,
  List<T>? initialSelected,
  String? searchHint,
  VoidCallback? onRefresh,
}) async {
  final result = await Navigator.push<List<T>>(
    context,
    TDSlidePopupRoute<List<T>>(
      slideTransitionFrom: SlideTransitionFrom.bottom,
      isDismissible: false,
      builder: (_) => _SearchablePickerSheet<T>(
        title: title,
        multiSelect: true,
        loader: loader,
        labelBuilder: labelBuilder,
        subtitleBuilder: subtitleBuilder,
        initialSelected: initialSelected,
        searchHint: searchHint,
        onRefresh: onRefresh,
      ),
    ),
  );
  return result ?? [];
}

// ═══ 内部实现 ═══

class _SearchablePickerSheet<T> extends StatefulWidget {
  final String title;
  final bool multiSelect;
  final PickerLoader<T> loader;
  final String Function(T item) labelBuilder;
  final String Function(T item)? subtitleBuilder;
  final List<T>? initialSelected;
  final String? searchHint;
  final VoidCallback? onRefresh;

  const _SearchablePickerSheet({
    required this.title,
    required this.multiSelect,
    required this.loader,
    required this.labelBuilder,
    this.subtitleBuilder,
    this.initialSelected,
    this.searchHint,
    this.onRefresh,
  });

  @override
  State<_SearchablePickerSheet<T>> createState() =>
      _SearchablePickerSheetState<T>();
}

class _SearchablePickerSheetState<T> extends State<_SearchablePickerSheet<T>> {
  final _scrollCtrl = ScrollController();

  List<T> _items = [];
  int _page = 1;
  bool _loading = true;
  bool _loadingMore = false;
  bool _hasMore = true;
  String _keyword = '';

  final Set<T> _selected = {};

  Timer? _debounce;

  @override
  void initState() {
    super.initState();
    if (widget.initialSelected != null) {
      _selected.addAll(widget.initialSelected!);
    }
    _scrollCtrl.addListener(_onScroll);
    _load();
  }

  @override
  void dispose() {
    _debounce?.cancel();
    _scrollCtrl.dispose();
    super.dispose();
  }

  void _onScroll() {
    if (_scrollCtrl.position.pixels >=
            _scrollCtrl.position.maxScrollExtent - 100 &&
        !_loadingMore &&
        _hasMore) {
      _loadMore();
    }
  }

  Future<void> _load({bool reset = false}) async {
    if (reset) {
      _page = 1;
      _hasMore = true;
      setState(() => _items = []);
    }
    if (_page == 1) setState(() => _loading = true);
    try {
      final items = await widget.loader(_keyword, _page);
      if (!mounted) return;
      setState(() {
        if (_page == 1) {
          _items = items;
        } else {
          _items.addAll(items);
        }
        _hasMore = items.length >= 20;
        _loading = false;
        _loadingMore = false;
      });
    } catch (_) {
      if (!mounted) return;
      setState(() {
        _loading = false;
        _loadingMore = false;
      });
    }
  }

  Future<void> _loadMore() async {
    if (_loadingMore || _loading || !_hasMore) return;
    _page++;
    setState(() => _loadingMore = true);
    await _load();
  }

  void _onSearch(String value) {
    _debounce?.cancel();
    _debounce = Timer(const Duration(milliseconds: 300), () {
      _keyword = value;
      _page = 1;
      setState(() => _items = []);
      _load(reset: true);
    });
  }

  void _onItemTap(T item) {
    setState(() {
      if (widget.multiSelect) {
        if (_selected.contains(item)) {
          _selected.remove(item);
        } else {
          _selected.add(item);
        }
      } else {
        // 单选：仅记录选中项，点击「确定」才提交
        _selected
          ..clear()
          ..add(item);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final screenHeight = MediaQuery.of(context).size.height;

    return SafeArea(
      child: Padding(
        padding: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
        ),
        child: Material(
          color: colors.bgCard,
          clipBehavior: Clip.antiAlias,
          borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
          child: ConstrainedBox(
            constraints: BoxConstraints(maxHeight: screenHeight * 0.8),
            child: Container(
              color: colors.bgPage,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  _buildHeader(colors),
                  _buildSearchBar(colors),
                  Expanded(
                    child: ColoredBox(
                      color: colors.bgCard,
                      child: _buildList(colors),
                    ),
                  ),
                  _buildFooter(colors),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildHeader(AppColorsExtension colors) {
    return Container(
      padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
      decoration: BoxDecoration(color: colors.bgCard),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Center(
            child: Container(
              width: 36,
              height: 4,
              margin: const EdgeInsets.only(bottom: 10),
              decoration: BoxDecoration(
                color: colors.border,
                borderRadius: BorderRadius.circular(2),
              ),
            ),
          ),
          Row(
            children: [
              const SizedBox(width: 22),
              Expanded(
                child: Text(
                  widget.title,
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.w600,
                    color: colors.textPrimary,
                  ),
                ),
              ),
              GestureDetector(
                onTap: () => Navigator.of(context).pop(),
                child: Icon(Icons.close, size: 22, color: colors.textSecondary),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildSearchBar(AppColorsExtension colors) {
    return Container(
      padding: const EdgeInsets.only(bottom: 8),
      decoration: BoxDecoration(
        color: colors.bgCard,
        border: Border(
          bottom: BorderSide(color: colors.border, width: 0.5),
        ),
      ),
      child: TDSearchBar(
        placeHolder:
            widget.searchHint ?? AppLocalizations.of(context).get('search'),
        style: TDSearchStyle.round,
        onTextChanged: _onSearch,
      ),
    );
  }

  Widget _buildList(AppColorsExtension colors) {
    if (_loading && _items.isEmpty) {
      return const Center(
        child: TDLoading(
          size: TDLoadingSize.medium,
          icon: TDLoadingIcon.activity,
        ),
      );
    }
    return EasyRefresh(
      header: TDRefreshHeader(),
      onRefresh: () async {
        widget.onRefresh?.call();
        await _load(reset: true);
      },
      child: _items.isEmpty
          ? ListView(
              children: [
                const SizedBox(height: 80),
                Center(
                  child: Text(
                    AppLocalizations.of(context).get('noData'),
                    style:
                        TextStyle(fontSize: 14, color: colors.textSecondary),
                  ),
                ),
              ],
            )
          : ListView.separated(
              controller: _scrollCtrl,
              padding: EdgeInsets.zero,
              itemCount: _items.length + 1,
              separatorBuilder: (_, _) =>
                  Divider(height: 1, thickness: 0.5, color: colors.border),
              itemBuilder: (context, index) {
                if (index == _items.length) {
                  if (_loadingMore) {
                    return const Padding(
                      padding: EdgeInsets.all(16),
                      child: Center(
                        child: TDLoading(
                          size: TDLoadingSize.small,
                          icon: TDLoadingIcon.activity,
                        ),
                      ),
                    );
                  }
                  return ListFooter(
                    itemCount: _items.length,
                    hasMore: _hasMore,
                  );
                }
                final item = _items[index];
                final label = widget.labelBuilder(item);
                final isSelected = _selected.contains(item);

                return _PickerItemTile(
                  label: label,
                  isSelected: isSelected,
                  isMultiSelect: widget.multiSelect,
                  onTap: () => _onItemTap(item),
                );
              },
            ),
    );
  }

  Widget _buildFooter(AppColorsExtension colors) {
    final l10n = AppLocalizations.of(context);
    final selectedText = _selected.map(widget.labelBuilder).join(';');
    return Container(
      padding: const EdgeInsets.fromLTRB(16, 10, 16, 10),
      decoration: BoxDecoration(
        color: colors.bgCard,
        border: Border(top: BorderSide(color: colors.border, width: 0.5)),
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 已选内容预览：单选/多选统一展示，多选以 ; 分隔，最多两行超出省略
          if (selectedText.isNotEmpty) ...[
            Text.rich(
              TextSpan(
                children: [
                  TextSpan(
                    text: l10n.get('selectedLabel'),
                    style: TextStyle(color: colors.textSecondary),
                  ),
                  TextSpan(
                    text: selectedText,
                    style: TextStyle(color: colors.primary),
                  ),
                ],
              ),
              maxLines: 2,
              overflow: TextOverflow.ellipsis,
              style: const TextStyle(fontSize: 13, height: 1.4),
            ),
            const SizedBox(height: 10),
          ],
          Row(
            children: [
              Expanded(
                child: GestureDetector(
                  onTap: () => Navigator.of(context).pop(),
                  child: Container(
                    height: 40,
                    decoration: BoxDecoration(
                      color: colors.bgSecondaryContainer,
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: Center(
                      child: Text(
                        l10n.get('cancel'),
                        style: TextStyle(
                          fontSize: 14,
                          color: colors.textSecondary,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: GestureDetector(
                  onTap: () {
                    if (widget.multiSelect) {
                      Navigator.of(context).pop(_selected.toList());
                    } else {
                      Navigator.of(context)
                          .pop(_selected.isEmpty ? null : _selected.first);
                    }
                  },
                  child: Container(
                    height: 40,
                    decoration: BoxDecoration(
                      color: colors.primary,
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: Center(
                      child: Text(
                        widget.multiSelect
                            ? '${l10n.get('confirm')}${_selected.isNotEmpty ? "(${_selected.length})" : ""}'
                            : l10n.get('confirm'),
                        style:
                            const TextStyle(fontSize: 14, color: Colors.white),
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

/// 选择器列表项。
class _PickerItemTile extends StatelessWidget {
  final String label;
  final bool isSelected;
  final bool isMultiSelect;
  final VoidCallback onTap;

  const _PickerItemTile({
    required this.label,
    required this.isSelected,
    required this.isMultiSelect,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;

    return GestureDetector(
      onTap: onTap,
      behavior: HitTestBehavior.opaque,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
        child: Row(
          children: [
            Icon(
              isMultiSelect
                  ? (isSelected
                      ? TDIcons.check_rectangle_filled
                      : TDIcons.rectangle)
                  : (isSelected ? TDIcons.check_circle_filled : TDIcons.circle),
              size: 22,
              color: isSelected ? colors.primary : colors.textPlaceholder,
            ),
            const SizedBox(width: 12),
            Expanded(
              child: Text(
                label,
                style: TextStyle(
                  fontSize: 15,
                  color: isSelected ? colors.primary : colors.textPrimary,
                  fontWeight:
                      isSelected ? FontWeight.w500 : FontWeight.normal,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
