import 'package:flutter/material.dart';

/// Renders markdown-like text as clean formatted text without raw symbols.
/// Supports: **bold**, *italic*, ### headings, - bullets, numbered lists.
class FormattedText extends StatelessWidget {
  final String text;
  final TextStyle baseStyle;

  const FormattedText({
    super.key,
    required this.text,
    required this.baseStyle,
  });

  @override
  Widget build(BuildContext context) {
    final lines = text.split('\n');
    final children = <Widget>[];

    for (int i = 0; i < lines.length; i++) {
      var line = lines[i];

      // Skip empty lines but add spacing
      if (line.trim().isEmpty) {
        if (children.isNotEmpty) {
          children.add(const SizedBox(height: 8));
        }
        continue;
      }

      // Heading lines (### / ## / #)
      final headingMatch = RegExp(r'^(#{1,4})\s+(.*)$').firstMatch(line.trim());
      if (headingMatch != null) {
        final level = headingMatch.group(1)!.length;
        final headingText = headingMatch.group(2)!;
        final fontSize = level <= 2 ? baseStyle.fontSize! + 2 : baseStyle.fontSize!;
        if (children.isNotEmpty) children.add(const SizedBox(height: 10));
        children.add(RichText(
          text: _buildSpan(headingText, baseStyle.copyWith(
            fontWeight: FontWeight.w700,
            fontSize: fontSize,
          )),
        ));
        children.add(const SizedBox(height: 4));
        continue;
      }

      // Bullet points (- or *)
      final bulletMatch = RegExp(r'^\s*[-*]\s+(.*)$').firstMatch(line);
      if (bulletMatch != null) {
        final bulletText = bulletMatch.group(1)!;
        children.add(Padding(
          padding: const EdgeInsets.only(left: 8, top: 2, bottom: 2),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding: const EdgeInsets.only(top: 6, right: 8),
                child: Container(
                  width: 5, height: 5,
                  decoration: BoxDecoration(
                    color: baseStyle.color?.withValues(alpha: 0.6),
                    shape: BoxShape.circle,
                  ),
                ),
              ),
              Expanded(child: RichText(text: _buildSpan(bulletText, baseStyle))),
            ],
          ),
        ));
        continue;
      }

      // Numbered list (1. 2. etc)
      final numMatch = RegExp(r'^\s*(\d+)[.)]\s+(.*)$').firstMatch(line);
      if (numMatch != null) {
        final num = numMatch.group(1)!;
        final numText = numMatch.group(2)!;
        children.add(Padding(
          padding: const EdgeInsets.only(left: 8, top: 2, bottom: 2),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              SizedBox(
                width: 24,
                child: Text('$num.', style: baseStyle.copyWith(fontWeight: FontWeight.w600)),
              ),
              Expanded(child: RichText(text: _buildSpan(numText, baseStyle))),
            ],
          ),
        ));
        continue;
      }

      // Normal text line
      children.add(RichText(text: _buildSpan(line, baseStyle)));
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: children,
    );
  }

  /// Parse inline **bold** and *italic* into TextSpans.
  TextSpan _buildSpan(String text, TextStyle style) {
    final spans = <InlineSpan>[];
    final pattern = RegExp(r'\*\*\*(.+?)\*\*\*|\*\*(.+?)\*\*|\*(.+?)\*');
    int lastEnd = 0;

    for (final match in pattern.allMatches(text)) {
      // Text before this match
      if (match.start > lastEnd) {
        spans.add(TextSpan(text: text.substring(lastEnd, match.start), style: style));
      }

      if (match.group(1) != null) {
        // ***bold italic***
        spans.add(TextSpan(
          text: match.group(1),
          style: style.copyWith(fontWeight: FontWeight.w700, fontStyle: FontStyle.italic),
        ));
      } else if (match.group(2) != null) {
        // **bold**
        spans.add(TextSpan(
          text: match.group(2),
          style: style.copyWith(fontWeight: FontWeight.w700),
        ));
      } else if (match.group(3) != null) {
        // *italic*
        spans.add(TextSpan(
          text: match.group(3),
          style: style.copyWith(fontStyle: FontStyle.italic),
        ));
      }

      lastEnd = match.end;
    }

    // Remaining text
    if (lastEnd < text.length) {
      spans.add(TextSpan(text: text.substring(lastEnd), style: style));
    }

    if (spans.isEmpty) {
      return TextSpan(text: text, style: style);
    }

    return TextSpan(children: spans);
  }
}
