import 'dart:async';
import 'dart:math';

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

import 'package:asciineverdie/data/race_data.dart';
import 'package:asciineverdie/src/shared/animation/front_screen_animation.dart';

/// 프론트 화면용 Hero vs Glitch God ASCII 애니메이션 위젯
///
/// 작은 용사가 거대한 Glitch God에 맞서는 루프 애니메이션
/// RichText로 문자별 색상 적용, 랜덤 종족 변경 지원
class HeroVsBossAnimation extends StatefulWidget {
  const HeroVsBossAnimation({super.key});

  @override
  State<HeroVsBossAnimation> createState() => _HeroVsBossAnimationState();
}

class _HeroVsBossAnimationState extends State<HeroVsBossAnimation> {
  int _currentFrame = 0;
  Timer? _animationTimer;
  Timer? _raceChangeTimer;
  final Random _random = Random();

  // 현재 종족 (랜덤 변경)
  String _currentRaceId = 'byte_human';
  int _raceIndex = 0;

  @override
  void initState() {
    super.initState();
    _startAnimation();
    _startRaceChangeTimer();
  }

  @override
  void dispose() {
    _animationTimer?.cancel();
    _raceChangeTimer?.cancel();
    super.dispose();
  }

  void _startAnimation() {
    _animationTimer = Timer.periodic(
      const Duration(milliseconds: frontScreenAnimationIntervalMs),
      (_) {
        if (!mounted) return;
        // 프레임 빌드 중이면 다음 프레임까지 대기
        if (SchedulerBinding.instance.schedulerPhase ==
            SchedulerPhase.persistentCallbacks) {
          SchedulerBinding.instance.addPostFrameCallback((_) {
            if (mounted) {
              setState(() {
                _currentFrame =
                    (_currentFrame + 1) % frontScreenAnimationFrameCount;
              });
            }
          });
        } else {
          setState(() {
            _currentFrame =
                (_currentFrame + 1) % frontScreenAnimationFrameCount;
          });
        }
      },
    );
  }

  /// 8초마다 랜덤 종족 변경
  void _startRaceChangeTimer() {
    _raceChangeTimer = Timer.periodic(
      const Duration(seconds: 8),
      (_) => _changeRace(),
    );
  }

  void _changeRace() {
    if (!mounted) return;

    final allRaces = RaceData.all;
    if (allRaces.isEmpty) return;

    // 프레임 빌드 중이면 다음 프레임까지 대기
    if (SchedulerBinding.instance.schedulerPhase ==
        SchedulerPhase.persistentCallbacks) {
      SchedulerBinding.instance.addPostFrameCallback((_) {
        if (mounted) {
          setState(() {
            _raceIndex = (_raceIndex + 1) % allRaces.length;
            _currentRaceId = allRaces[_raceIndex].raceId;
          });
        }
      });
    } else {
      setState(() {
        _raceIndex = (_raceIndex + 1) % allRaces.length;
        _currentRaceId = allRaces[_raceIndex].raceId;
      });
    }
  }

  /// 글리치 효과: 랜덤 문자 대체
  String _applyGlitchEffect(String frame) {
    // 10% 확률로 글리치 효과 적용
    if (_random.nextDouble() > 0.1) return frame;

    const glitchChars = '@#\$%&*!?~';
    final chars = frame.split('');
    final glitchCount = _random.nextInt(5) + 1;

    for (var i = 0; i < glitchCount; i++) {
      final pos = _random.nextInt(chars.length);
      if (chars[pos] != ' ' && chars[pos] != '\n') {
        chars[pos] = glitchChars[_random.nextInt(glitchChars.length)];
      }
    }

    return chars.join();
  }

  /// 문자별 색상 결정
  Color _getCharColor(String char) {
    // 공격/이펙트 (시안)
    if ('><=!+'.contains(char)) return Colors.cyan;
    // 데미지/글리치 (마젠타)
    if ('*~@#\$%&'.contains(char)) return const Color(0xFFFF00FF);
    // 보스 눈 (빨강)
    if ('◈◉X'.contains(char)) return Colors.red;
    // 보스 타이틀 텍스트 (시안)
    if ('GLITCH'.contains(char) || 'GOD'.contains(char)) return Colors.cyan;
    // 기본 (흰색)
    return Colors.white;
  }

  /// 문자열을 색상별 TextSpan으로 변환
  TextSpan _buildColoredTextSpan(String text) {
    final spans = <TextSpan>[];

    for (final char in text.split('')) {
      final color = _getCharColor(char);
      spans.add(
        TextSpan(
          text: char,
          style: TextStyle(
            fontFamily: 'JetBrainsMono',
            fontSize: 15,
            height: 1.1,
            color: color,
            letterSpacing: 0,
          ),
        ),
      );
    }

    return TextSpan(children: spans);
  }

  @override
  Widget build(BuildContext context) {
    final frame = _applyGlitchEffect(frontScreenAnimationFrames[_currentFrame]);

    // 현재 종족 이름 (UI 표시용)
    final raceName = RaceData.findById(_currentRaceId)?.name ?? 'Hero';

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
      decoration: BoxDecoration(
        // 항상 검은 배경
        color: Colors.black,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: Colors.white24, width: 1),
        // 은은한 글로우 효과
        boxShadow: [
          BoxShadow(
            color: Colors.cyan.withValues(alpha: 0.15),
            blurRadius: 20,
            spreadRadius: 2,
          ),
        ],
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          // ASCII 애니메이션 (컬러 적용) - 남은 공간 차지
          Flexible(
            child: FittedBox(
              fit: BoxFit.scaleDown,
              child: RichText(text: _buildColoredTextSpan(frame)),
            ),
          ),
          const SizedBox(height: 8),
          // 하단 효과 바 (컬러)
          _buildEffectBar(),
          const SizedBox(height: 4),
          // 현재 종족 표시
          Text(
            '♦ $raceName',
            style: TextStyle(
              fontFamily: 'JetBrainsMono',
              fontSize: 15,
              color: Colors.cyan.withValues(alpha: 0.7),
            ),
          ),
        ],
      ),
    );
  }

  /// 하단 효과 바: 글리치/전투 효과 시각화
  Widget _buildEffectBar() {
    // 프레임에 따라 색상 변화
    final colors = [
      Colors.cyan,
      Colors.purple,
      Colors.red,
      Colors.cyan,
      Colors.yellow,
      Colors.purple,
    ];
    final currentColor = colors[_currentFrame % colors.length];

    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        // 왼쪽 검 아이콘 (용사)
        Icon(
          Icons.flash_on,
          size: 14,
          color: Colors.yellow.withValues(alpha: 0.8),
        ),
        const SizedBox(width: 8),
        // 중앙 효과 바
        Expanded(
          child: Container(
            height: 3,
            decoration: BoxDecoration(
              gradient: LinearGradient(
                colors: [
                  Colors.transparent,
                  currentColor.withValues(alpha: 0.7),
                  Colors.white.withValues(alpha: 0.9),
                  currentColor.withValues(alpha: 0.7),
                  Colors.transparent,
                ],
              ),
              borderRadius: BorderRadius.circular(2),
            ),
          ),
        ),
        const SizedBox(width: 8),
        // 오른쪽 보스 아이콘
        Icon(
          Icons.whatshot,
          size: 14,
          color: Colors.red.withValues(alpha: 0.8),
        ),
      ],
    );
  }
}
