// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

import 'package:flutter/material.dart';
import 'package:wyatt_component_copy_with_extension/component_copy_with_extension.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';

part 'rich_text_builder.g.dart';

@ComponentCopyWithExtension()
class RichTextBuilder extends RichTextBuilderComponent
    with $RichTextBuilderCWMixin {
  const RichTextBuilder({
    super.text,
    super.parser,
    super.defaultStyle,
    super.styles,
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    final RegExp regex = RegExp(r'<(.*?)>(.*?)<\/\1>');
    final root = RichTextNode.from(
      text ?? '',
      regex,
      RichTextStyleParameter(
        ThemeHelper.getThemeElement<TextStyle, TextStyle>(
          [
            defaultStyle,
            Theme.of(context)
                .extension<RichTextBuilderThemeExtension>()
                ?.defaultStyle,
            context.textTheme.bodyMedium,
          ],
          valueValidator: (style) => style != null,
          transform: (style) => style,
        ),
        ThemeHelper.getThemeElement<Map<String, TextStyle>,
            Map<String, TextStyle>>(
          [
            styles,
            Theme.of(context)
                .extension<RichTextBuilderThemeExtension>()
                ?.styles,
            const <String, TextStyle>{},
          ],
          valueValidator: (styles) => styles != null,
          transform: (styles) => styles,
        )!,
        null,
      ),
    );
    final customParser = parser ??
        RichTextParser(
          nodeBuilder: (content, style) {
            if (style is GradientTextStyle?) {
              return WidgetSpan(
                child: GradientText(
                  content,
                  style: style,
                  softWrap: true,
                  textHeightBehavior: const TextHeightBehavior(
                    applyHeightToLastDescent: false,
                  ),
                ),
                style: style,
              );
            }
            return TextSpan(
              text: content,
              style: style,
            );
          },
        );
    return Text.rich(
      TextSpan(children: [root.toInlineSpan(customParser)]),
      textHeightBehavior:
          const TextHeightBehavior(applyHeightToLastDescent: false),
    );
  }
}
