part of '../async_action_button.dart';

class AsyncListTile extends StatefulWidget {
  final AsyncActionCallback onPressed;
  final Widget? leading;
  final Widget title;
  final Widget? subtitle;
  final bool closeOnSuccess;
  final VoidCallback? onSuccess;
  final AsyncErrorBuilder? errorBuilder;
  final bool enabled;

  const AsyncListTile({
    required this.onPressed,
    required this.title,
    this.leading,
    this.subtitle,
    this.closeOnSuccess = true,
    this.onSuccess,
    this.errorBuilder,
    this.enabled = true,
    super.key,
  });

  @override
  State<AsyncListTile> createState() => _AsyncListTileState();
}

class _AsyncListTileState extends State<AsyncListTile> {
  final AsyncActionController _controller = AsyncActionController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  Future<void> _handleTap() async {
    final ok = await _controller.run(
      widget.onPressed,
      errorBuilder: widget.errorBuilder,
    );
    if (!mounted) return;
    if (ok) {
      widget.onSuccess?.call();
      if (widget.closeOnSuccess && Navigator.of(context).canPop()) {
        Navigator.of(context).pop();
      }
    }
  }

  @override
  Widget build(BuildContext context) => AnimatedBuilder(
    animation: _controller,
    builder: (context, _) {
      final busy = _controller.busy;
      final err = _controller.error;
      final leading = busy
          ? const SizedBox(
              width: 24,
              height: 24,
              child: AppProgressIndicator.small(),
            )
          : widget.leading;
      return Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          ListTile(
            leading: leading,
            title: widget.title,
            subtitle: widget.subtitle,
            enabled: widget.enabled && !busy,
            onTap: busy ? null : _handleTap,
          ),
          if (err != null)
            Padding(
              padding: const EdgeInsets.only(left: 16, right: 16, bottom: 8),
              child: Text(err, style: _asyncErrorTextStyle(context)),
            ),
        ],
      );
    },
  );
}
