import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'robot_painter.dart';

export 'robot_painter.dart' show RobotState;

/// Animated robot avatar widget.
/// Automatically drives animations based on [state].
class RobotAvatar extends StatefulWidget {
  final RobotState state;
  final double size;

  const RobotAvatar({
    super.key,
    this.state = RobotState.idle,
    this.size = 56,
  });

  @override
  State<RobotAvatar> createState() => _RobotAvatarState();
}

class _RobotAvatarState extends State<RobotAvatar>
    with TickerProviderStateMixin {
  late AnimationController _mainCtrl;
  late AnimationController _blinkCtrl;

  @override
  void initState() {
    super.initState();

    _mainCtrl = AnimationController(vsync: this)
      ..addListener(() => setState(() {}));
    _blinkCtrl = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 150),
    )..addListener(() => setState(() {}));

    _startAnimations(widget.state);
    _scheduleBlink();
  }

  @override
  void didUpdateWidget(RobotAvatar old) {
    super.didUpdateWidget(old);
    if (old.state != widget.state) {
      _mainCtrl.stop();
      _startAnimations(widget.state);
    }
  }

  void _startAnimations(RobotState state) {
    switch (state) {
      case RobotState.idle:
        _mainCtrl.duration = const Duration(milliseconds: 2400);
        _mainCtrl.repeat(reverse: true);
      case RobotState.thinking:
        _mainCtrl.duration = const Duration(milliseconds: 900);
        _mainCtrl.repeat();
      case RobotState.executing:
        _mainCtrl.duration = const Duration(milliseconds: 600);
        _mainCtrl.repeat();
      case RobotState.speaking:
        _mainCtrl.duration = const Duration(milliseconds: 700);
        _mainCtrl.repeat();
      case RobotState.alert:
        _mainCtrl.duration = const Duration(milliseconds: 500);
        _mainCtrl.repeat();
    }
  }

  Future<void> _scheduleBlink() async {
    while (mounted) {
      // Wait 2-5 seconds between blinks
      final pause = 2000 + math.Random().nextInt(3000);
      await Future.delayed(Duration(milliseconds: pause));
      if (!mounted) break;
      // Only blink during non-thinking states
      if (widget.state != RobotState.thinking &&
          widget.state != RobotState.executing) {
        await _blinkCtrl.forward();
        await Future.delayed(const Duration(milliseconds: 60));
        if (!mounted) break;
        await _blinkCtrl.reverse();
      }
    }
  }

  @override
  void dispose() {
    _mainCtrl.dispose();
    _blinkCtrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Apply a subtle breathing scale for idle state
    final scale = widget.state == RobotState.idle
        ? 1.0 + 0.03 * _mainCtrl.value
        : widget.state == RobotState.alert
            ? 1.0 + 0.05 * math.sin(_mainCtrl.value * math.pi)
            : 1.0;

    return Transform.scale(
      scale: scale,
      child: SizedBox(
        width: widget.size,
        height: widget.size,
        child: CustomPaint(
          painter: RobotPainter(
            state: widget.state,
            anim: _mainCtrl.value,
            blink: _blinkCtrl.value,
          ),
        ),
      ),
    );
  }
}
