// Flutter imports:
import 'package:flutter/material.dart';

// Package imports:
import 'package:google_fonts/google_fonts.dart';
import 'package:remever/common/resources.dart';
import 'package:remever/components/extensions/context.dart';

export '../../common/typography.dart';

abstract class TypographyType {
  ///
  /// Размер шрифта
  ///
  double get size;

  ///
  /// Получение [TextStyle] для типа шрифта
  ///
  TextStyle get style;
}

abstract class TypographyTypeRegular extends TypographyType {
  ///
  /// Высота линии
  ///
  double get height => 1.21;

  @override
  TextStyle get style {
    return GoogleFonts.inter(
      fontWeight: FontWeight.w400,
      fontSize: size.sp,
      height: height,
      color: AppColors.text_black,
    );
  }
}

abstract class TypographyTypeMedium extends TypographyType {
  ///
  /// Высота линии
  ///
  double get height => 1.15;

  @override
  TextStyle get style {
    return GoogleFonts.inter(
      fontWeight: FontWeight.w500,
      fontSize: size.sp,
      height: height,
      color: AppColors.text_black,
    );
  }
}

abstract class TypographyTypeSemiBold extends TypographyType {
  ///
  /// Высота линии
  ///
  double get height => 1.21;

  @override
  TextStyle get style {
    return GoogleFonts.inter(
      fontWeight: FontWeight.w600,
      fontSize: size.sp,
      height: height,
      color: AppColors.text_black,
    );
  }
}

abstract class TypographyTypeBold extends TypographyType {
  ///
  /// Высота линии
  ///
  double get height => 1.21;

  @override
  TextStyle get style {
    return GoogleFonts.inter(
      fontWeight: FontWeight.w700,
      fontSize: size.sp,
      height: height,
      color: AppColors.text_black,
    );
  }
}

abstract class TypographyTypeHeadBold extends TypographyType {
  ///
  /// Высота линии
  ///
  double get height => 1.36;

  @override
  TextStyle get style {
    return GoogleFonts.inter(
      fontWeight: FontWeight.w700,
      fontSize: size.sp,
      height: height,
      color: AppColors.text_black,
    );
  }
}

///
/// Дополнительные возможности [AppTypography]
///
enum TypographyFeature {
  ///
  /// Использование [Text]
  ///
  DEFAULT,

  ///
  /// Использование [RichText]
  ///
  RICH,

  ///
  /// Использование [SelectableText]
  ///
  SELECTABLE,
}

///
/// Виджет для отображения текста в приложении
///
/// Тесно использует [TypographyType]
/// На его основе выбирается стиль текста
///
/// Важно: планшетная верстка не учитывается в стилях - меняется сам стиль,
/// поэтому контролировать нужно извне
///
class AppTypography extends StatelessWidget {
  const AppTypography(
    this.text, {
    this.type,
    this.color,
    this.maxLines = 1,
    this.textAlign = TextAlign.left,
    this.fontWeight,
    this.overflow = TextOverflow.ellipsis,
    this.height,
    this.softWrap,
    this.textDecoration = TextDecoration.none,
    super.key,
  }) : typographyFeature = TypographyFeature.DEFAULT,
       children = null;

  const AppTypography.rich(
    this.text, {
    this.type,
    this.color,
    this.maxLines,
    this.textAlign = TextAlign.left,
    this.fontWeight,
    this.overflow,
    this.height,
    this.softWrap,
    this.textDecoration = TextDecoration.none,
    this.children,
    super.key,
  }) : typographyFeature = TypographyFeature.RICH;

  const AppTypography.selectable(
    this.text, {
    this.type,
    this.color,
    this.maxLines,
    this.textAlign = TextAlign.left,
    this.fontWeight,
    this.overflow,
    this.height,
    this.softWrap,
    this.textDecoration = TextDecoration.none,
    super.key,
  }) : typographyFeature = TypographyFeature.SELECTABLE,
       children = null;

  /// Текст
  final String text;

  /// Стиль текста
  final TypographyType? type;

  /// Цвет текста
  final Color? color;

  /// Кол-во линий
  final int? maxLines;

  /// Направление текста
  final TextAlign textAlign;

  /// Жирность шрифта
  final FontWeight? fontWeight;

  /// Overflow
  final TextOverflow? overflow;

  /// Межстрочный интервал
  final double? height;

  /// Мягкий перенос
  final bool? softWrap;

  /// Декорация текста
  final TextDecoration textDecoration;

  /// Использование фич типографии
  final TypographyFeature typographyFeature;

  /// Список [TextSpan]
  final List<InlineSpan>? children;

  @override
  Widget build(BuildContext context) {
    final DefaultTextStyle textStyle = DefaultTextStyle.of(context);

    final TextStyle computeTextStyle =
        type == null
            ? textStyle.style
            : type!.style.copyWith(
              color: color ?? Colors.black,
              fontWeight: fontWeight,
              height: height,
              decoration: textDecoration,
            );

    switch (typographyFeature) {
      case TypographyFeature.DEFAULT:
        return Text(
          text,
          maxLines: maxLines,
          textAlign: textAlign,
          overflow: overflow,
          softWrap: softWrap,
          style: computeTextStyle,
        );

      case TypographyFeature.RICH:
        return RichText(
          text: TextSpan(
            text: text,
            children: children,
            style: computeTextStyle,
          ),
        );

      case TypographyFeature.SELECTABLE:
        return SelectableText(
          text,
          maxLines: maxLines,
          textAlign: textAlign,
          style: computeTextStyle,
        );
    }
  }
}
