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

/// [수정] "SBSPACE"를 한 줄로 그리는 IntroView
///
/// @param mainColor 뷰의 텍스트 색상 (S, B 강조)
/// @param onAnimationFinished 뷰의 애니메이션이 완료될 때 호출될 콜백
class IntroViewFlutter extends StatefulWidget {
  final Color mainColor;
  final VoidCallback onAnimationFinished;

  const IntroViewFlutter({
    super.key,
    required this.mainColor,
    required this.onAnimationFinished,
  });

  @override
  _IntroViewFlutterState createState() => _IntroViewFlutterState();
}

class _IntroViewFlutterState extends State<IntroViewFlutter>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;

  late final Animation<int> _logoTextAnimation; // 0 -> 7
  late final Animation<int> _missionTextAnimation; // 0 -> 15

  static const String _logoString = "SBSPACE";
  static const String _missionString = "Simple is Best.";
  static const String _fontFamily = "Sdmisaeng";

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

    const int logoDuration = _logoString.length * 150; // 7 * 150ms = 1050ms
    const int missionDuration = _missionString.length * 100; // 15 * 100ms = 1500ms
    final int totalAnimationDuration = logoDuration + missionDuration; // 2550ms

    _controller = AnimationController(
      duration: Duration(milliseconds: totalAnimationDuration),
      vsync: this,
    );

    // 로고 타이핑 애니메이션 (0 -> 7)
    _logoTextAnimation = IntTween(begin: 0, end: _logoString.length).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Interval(
          0.0,
          logoDuration / totalAnimationDuration,
          curve: Curves.linear,
        ),
      ),
    );

    // 미션 타이핑 애니메이션 (0 -> 15)
    _missionTextAnimation = IntTween(begin: 0, end: _missionString.length).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Interval(
          logoDuration / totalAnimationDuration,
          1.0,
          curve: Curves.linear,
        ),
      ),
    );

    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        Future.delayed(const Duration(seconds: 1), () {
          if (mounted) {
            widget.onAnimationFinished();
          }
        });
      }
    });

    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return CustomPaint(
          painter: _IntroPainter(
            mainColor: widget.mainColor,
            fontFamily: _fontFamily,
            logoTextLength: _logoTextAnimation.value,
            missionTextLength: _missionTextAnimation.value,
          ),
          size: Size.infinite,
        );
      },
    );
  }
}

/// [수정] RichText(TextSpan)를 사용해 그리는 CustomPainter
class _IntroPainter extends CustomPainter {
  final Color mainColor;
  final String fontFamily;
  final int logoTextLength;
  final int missionTextLength;

  static const String _logoString = "SBSPACE";
  static const String _missionString = "Simple is Best.";

  _IntroPainter({
    required this.mainColor,
    required this.fontFamily,
    required this.logoTextLength,
    required this.missionTextLength,
  });

  /// 헬퍼: 현재 길이에 맞는 "SBSPACE" TextSpan을 생성
  TextSpan _buildLogoSpan(int length) {
    final Color normalColor = mainColor.withOpacity(0.6);
    final List<TextSpan> children = [];

    if (length >= 1) {
      children.add(TextSpan(text: "S", style: TextStyle(color: mainColor)));
    }
    if (length >= 2) {
      children.add(TextSpan(text: "B", style: TextStyle(color: mainColor)));
    }
    if (length >= 3) {
      final String spaceToDraw = _logoString.substring(2, length.clamp(2, _logoString.length));
      children.add(TextSpan(text: spaceToDraw, style: TextStyle(color: normalColor)));
    }

    return TextSpan(
      style: TextStyle(fontFamily: fontFamily, fontWeight: FontWeight.bold),
      children: children,
    );
  }

  /// 헬퍼: TextSpan과 폰트 크기로 TextPainter를 생성 (레이아웃 포함)
  TextPainter _createTextPainter(TextSpan textSpan, double fontSize) {
    final style = textSpan.style!.copyWith(fontSize: fontSize);
    
    final painter = TextPainter(
      text: TextSpan(children: textSpan.children, style: style),
      textDirection: TextDirection.ltr,
    );
    painter.layout();
    return painter;
  }

  @override
  void paint(Canvas canvas, Size size) {
    // 1. 로고 폰트 크기 정의
    final double logoFontSize = size.shortestSide / 6.0;

    // 2. 미션 폰트 크기를 화면 너비에 꽉 차게 동적 계산
    
    // 2a. 임시 폰트 크기(100)로 TextPainter를 생성하여 원본 너비를 측정
    const double tempMissionFontSize = 100.0;
    final TextPainter tpMissionTemp = TextPainter(
      text: TextSpan(
        text: _missionString,
        style: TextStyle(fontFamily: fontFamily, fontWeight: FontWeight.bold, fontSize: tempMissionFontSize)
      ),
      textDirection: TextDirection.ltr,
    )..layout();

    // 2b. (화면 너비 * 0.9) / (임시 텍스트 너비) = 스케일 비율
    final double targetWidth = size.width * 0.9;
    final double scale = targetWidth / tpMissionTemp.width;
    
    // 2c. 실제 폰트 크기 계산
    final double missionFontSize = tempMissionFontSize * scale;

    // 3. 레이아웃 계산용 TextPainter (항상 전체 텍스트 기준)
    
    // 3a. 로고
    final tpLogoFull = _createTextPainter(_buildLogoSpan(_logoString.length), logoFontSize);
    
    // 3b. 미션 (계산된 missionFontSize 사용)
    final TextPainter tpMissionFull = TextPainter(
      text: TextSpan(
        text: _missionString,
        style: TextStyle(
          color: mainColor,
          fontSize: missionFontSize,
          fontFamily: fontFamily,
          fontWeight: FontWeight.bold
        )
      ),
      textDirection: TextDirection.ltr,
    )..layout();


    // 4. 전체 텍스트 블록의 세로 중앙 정렬 Y좌표 계산
    final double padding = logoFontSize * 0.1;
    final double totalHeight = tpLogoFull.height + padding + tpMissionFull.height;
    final double startyLogo = (size.height - totalHeight) / 2.0;
    final double startyMission = startyLogo + tpLogoFull.height + padding;

    // 5. 각 텍스트 라인의 가로 중앙 정렬 X좌표 계산
    final double startxLogo = (size.width - tpLogoFull.width) / 2.0;
    final double startxMission = (size.width - tpMissionFull.width) / 2.0;

    // 6. 그리기용 TextPainter (애니메이션 적용된 길이 기준)
    
    // 6a. 로고 그리기 (현재 길이: logoTextLength)
    final tpLogoSub = _createTextPainter(_buildLogoSpan(logoTextLength), logoFontSize);
    tpLogoSub.paint(canvas, Offset(startxLogo, startyLogo));

    // 6b. 미션 그리기 (현재 길이: missionTextLength)
    final String missionToDraw = _missionString.substring(0, missionTextLength);
    final tpMissionSub = TextPainter(
      text: TextSpan(text: missionToDraw, style: tpMissionFull.text!.style), 
      textDirection: TextDirection.ltr,
    )..layout();
    
    tpMissionSub.paint(canvas, Offset(startxMission, startyMission));
  }

  @override
  bool shouldRepaint(covariant _IntroPainter oldDelegate) {
    return oldDelegate.mainColor != mainColor ||
        oldDelegate.logoTextLength != logoTextLength ||
        oldDelegate.missionTextLength != missionTextLength;
  }
}