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

import 'alert_dialog.dart';

class VDialogSelect<T, TValue> extends StatelessWidget {
  /// 数据集
  final List<T> source;

  /// 初始值
  final TValue? initialValue;

  /// 弹窗标题
  final String? title;

  /// 选项文本提取函数
  final String Function(T data)? labelGetter;

  /// 选项外显组件构建器
  final Widget Function(T data)? labelBuilder;

  /// 选项值提取函数
  final TValue Function(T data) valueGetter;

  const VDialogSelect({
    super.key,
    required this.source,
    this.title,
    this.initialValue,
    this.labelGetter,
    this.labelBuilder,
    required this.valueGetter,
  }) : assert(labelGetter != null || labelBuilder != null);

  Future<T?> show<T>() => VAlertDialog.showDialog<T>(this);

  @override
  Widget build(BuildContext context) {
    return VAlertDialog(
      width: 460,
      title: title,
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: _buildOptions(context),
      ),
      showCancel: true,
    );
  }

  List<Widget> _buildOptions(BuildContext context) {
    final primaryColor = Theme.of(context).primaryColor;
    final children = <Widget>[];
    for (var i = 0; i < source.length; i++) {
      final data = source[i];
      final val = valueGetter(data);
      final isSelected = initialValue == val;
      Widget label;
      if (labelBuilder != null) {
        label = labelBuilder!(data);
      } else {
        label = Text(
          labelGetter!(data),
          style: TextStyle(
            color: isSelected ? primaryColor : Colors.black,
            fontSize: 20,
          ),
        );
      }

      final widget = Container(
        alignment: Alignment.centerLeft,
        height: 56,
        color: isSelected ? Theme.of(context).secondaryHeaderColor : null,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [const SizedBox(width: 20), label],
            ),
            if (isSelected)
              Row(
                children: [
                  Icon(
                    Icons.check,
                    size: 24,
                    color: primaryColor,
                  ),
                  const SizedBox(width: 20)
                ],
              ),
          ],
        ),
      );
      children.add(
        Material(
          color: Colors.transparent,
          child: Ink(
            child: InkWell(
              onTap: () {
                _onSelected(val);
              },
              child: widget,
            ),
          ),
        ),
      );
    }
    return children;
  }

  void _onSelected(TValue value) {
    Get.back(result: value);
  }
}
