import 'package:flutter/material.dart';

class TypingDots extends StatefulWidget {
  const TypingDots({super.key, this.size = 6, this.color, this.spacing = 4});

  final double size;
  final double spacing;
  final Color? color;

  @override
  State<TypingDots> createState() => _TypingDotsState();
}

class _TypingDotsState extends State<TypingDots>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1200),
    )..repeat();
  }

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

  double _opacity(double t, double offset) {
    final phase = (t + offset) % 1.0;
    final distance = (phase - 0.5).abs();
    final ramp = 1.0 - (distance / 0.5);
    return 0.3 + 0.7 * ramp.clamp(0.0, 1.0);
  }

  @override
  Widget build(BuildContext context) {
    final color =
        widget.color ?? Theme.of(context).colorScheme.onSurfaceVariant;
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        final t = _controller.value;
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            _dot(color, _opacity(t, 0.0)),
            SizedBox(width: widget.spacing),
            _dot(color, _opacity(t, 0.2)),
            SizedBox(width: widget.spacing),
            _dot(color, _opacity(t, 0.4)),
          ],
        );
      },
    );
  }

  Widget _dot(Color color, double opacity) {
    return Opacity(
      opacity: opacity,
      child: Container(
        width: widget.size,
        height: widget.size,
        decoration: BoxDecoration(color: color, shape: BoxShape.circle),
      ),
    );
  }
}
