import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:intl/intl.dart';

extension CapExtension on String {
  String get toCamelCase => "${this[0].toUpperCase()}${substring(1)}";

  String get inCaps => '${this[0].toUpperCase()}${substring(1)}';

  String get allInCaps => toUpperCase();

  String get needTranslation => this;

  String get capitalizeFirstofEach => trim().isNotEmpty ? trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : "";
}

extension EmailValidator on String {
  Widget get toWidget => Text(this);

  Widget toText8(
          {bool isEnglishOnly = false,
          Color? color,
          FontWeight? fontWeight,
          bool isBold = false,
          int? maxlines,
          FontStyle? fontStyle,
          TextOverflow? textOverflow}) =>
      Text(
        this,
        maxLines: maxlines,
        overflow: textOverflow,
        style: TextStyle(
          fontSize: 8.f,
          fontStyle: fontStyle ?? FontStyle.normal,
          fontWeight: fontWeight ?? (isBold ? FontWeight.bold : FontWeight.normal),
          color: color ?? AppColors.blackColor,
          letterSpacing: 0,
          fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins',
        ),
      );

  Widget toText10(
          {bool isEnglishOnly = false,
          Color? color,
          FontWeight? weight,
          bool isBold = false,
          bool isUnderLine = false,
          bool isCenter = false,
          int? maxlines,
          FontStyle? fontStyle,
          TextOverflow? textOverflow,
          double letterSpacing = 0}) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        maxLines: maxlines,
        overflow: textOverflow,
        style: TextStyle(
            fontSize: 10.f,
            fontStyle: fontStyle ?? FontStyle.normal,
            fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
            color: color ?? AppColors.blackColor,
            letterSpacing: letterSpacing,
            decoration: isUnderLine ? TextDecoration.underline : null,
            fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins',
            decorationColor: color ?? AppColors.blackColor),
      );

  Widget toText9(
          {Color? color,
          FontWeight? weight,
          bool isBold = false,
          bool isUnderLine = false,
          bool isCenter = false,
          int? maxlines,
          FontStyle? fontStyle,
          TextOverflow? textOverflow,
          double letterSpacing = 0,
          bool isEnglishOnly = false}) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        maxLines: maxlines,
        overflow: textOverflow,
        style: TextStyle(
            fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins',
            fontSize: 9.f,
            fontStyle: fontStyle ?? FontStyle.normal,
            fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
            color: color ?? AppColors.blackColor,
            letterSpacing: letterSpacing,
            decoration: isUnderLine ? TextDecoration.underline : null,
            decorationColor: color ?? AppColors.blackColor),
      );

  Widget toText11({
    Color? color,
    FontWeight? weight,
    bool isUnderLine = false,
    bool isCenter = false,
    bool isBold = false,
    int maxLine = 0,
    double letterSpacing = 0,
    bool isEnglishOnly = false,
  }) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        maxLines: (maxLine > 0) ? maxLine : null,
        softWrap: true,
        style: TextStyle(
          fontSize: 11.f,
          fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
          color: color ?? AppColors.blackColor,
          letterSpacing: letterSpacing,
          decoration: isUnderLine ? TextDecoration.underline : null,
          fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins',
        ),
      );

  Widget toText12(
          {bool isEnglishOnly = false,
          Color? color,
          Color? decorationColor,
          bool isUnderLine = false,
          TextAlign textAlignment = TextAlign.start,
          bool isBold = false,
          FontWeight? fontWeight,
          bool isCenter = false,
          double? height,
          double? letterSpacing,
          TextOverflow? textOverflow,
          int maxLine = 0}) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : textAlignment,
        maxLines: (maxLine > 0) ? maxLine : null,
        style: TextStyle(
          overflow: textOverflow,
          fontSize: 12.f,
          fontWeight: fontWeight ?? (isBold ? FontWeight.bold : FontWeight.normal),
          color: color ?? AppColors.blackColor,
          letterSpacing: letterSpacing ?? 0,
          height: height,
          decorationColor: decorationColor ?? AppColors.blackColor,
          decoration: isUnderLine ? TextDecoration.underline : null,
          fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins',
        ),
      );

  Widget toText12Auto({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) => AutoSizeText(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        maxLines: (maxLine > 0) ? maxLine : null,
        minFontSize: 8,
        style: TextStyle(
          fontSize: 12.f,
          fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
          color: color ?? AppColors.blackColor,
          letterSpacing: 0,
          decoration: isUnderLine ? TextDecoration.underline : null,
        ),
      );

  Widget toTextAuto({
    Color? color,
    bool isUnderLine = false,
    bool isBold = false,
    bool isCenter = false,
    int maxLine = 0,
    double fontSize = 12,
    double letterSpacing = 0.64,
    double height = 1,
    TextOverflow? textOverflow,
    FontWeight? fontWeight,
  }) =>
      AutoSizeText(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        maxLines: (maxLine > 0) ? maxLine : null,
        minFontSize: 5,
        overflow: textOverflow,
        softWrap: true,
        style: TextStyle(
          fontSize: fontSize,
          fontWeight: fontWeight ?? (isBold ? FontWeight.bold : FontWeight.normal),
          color: color ?? AppColors.blackColor,
          letterSpacing: letterSpacing,
          decoration: isUnderLine ? TextDecoration.underline : null,
        ),
      );

  Widget toText13(
          {Color? color,
          bool isUnderLine = false,
          bool isBold = false,
          bool isCenter = false,
          int maxLine = 0,
          FontWeight? weight,
          double? letterSpacing = 0}) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        maxLines: (maxLine > 0) ? maxLine : null,
        style: TextStyle(
            fontSize: 13.f,
            fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
            color: color ?? AppColors.blackColor,
            letterSpacing: letterSpacing,
            decoration: isUnderLine ? TextDecoration.underline : null),
      );

  Widget toText14({
    bool isEnglishOnly = false,
    Color? color,
    bool isUnderLine = false,
    bool isBold = false,
    bool isCenter = false,
    FontWeight? weight,
    int? maxlines,
    double? letterSpacing = 0,
    double? height,
    String? fontFamily,
    TextOverflow? textOverflow,
  }) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        maxLines: maxlines,
        overflow: textOverflow,
        style: TextStyle(
            color: color ?? AppColors.blackColor,
            fontSize: 14.f,
            letterSpacing: letterSpacing,
            height: height,
            fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
            decoration: isUnderLine ? TextDecoration.underline : null,
            fontFamily: fontFamily ??
                (isEnglishOnly
                    ? "Poppins"
                    : getIt.get<AppState>().getLanguageCode() == "ar"
                        ? 'CairoArabic'
                        : 'Poppins'),
            decorationColor: color ?? AppColors.blackColor),
      );

  Widget toText15(
          {Color? color,
          bool isUnderLine = false,
          bool isBold = false,
          bool isCenter = false,
          FontWeight? weight,
          int? maxlines,
          double? letterSpacing = -1}) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        maxLines: maxlines,
        style: TextStyle(
            color: color ?? AppColors.blackColor,
            fontSize: 15.f,
            letterSpacing: letterSpacing,
            fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
            decoration: isUnderLine ? TextDecoration.underline : null),
      );

  Widget toText16(
          {bool isEnglishOnly = false,
          Color? color,
          bool isUnderLine = false,
          bool isBold = false,
          bool isCenter = false,
          int? maxlines,
          double? height,
          TextAlign? textAlign,
          FontWeight? weight,
          TextOverflow? textOverflow,
          String? fontFamily,
          double? letterSpacing = -0.4,
          Color? decorationColor}) =>
      Text(
        this,
        maxLines: maxlines,
        textAlign: isCenter ? textAlign ?? TextAlign.center : null,
        // locale: Locale('en', 'US'),
        style: TextStyle(
            color: color ?? AppColors.blackColor,
            fontSize: 16.f,
            letterSpacing: letterSpacing,
            height: height,
            overflow: textOverflow,
            fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
            decoration: isUnderLine ? TextDecoration.underline : null,
            fontFamily: fontFamily ??
                (isEnglishOnly
                    ? "Poppins"
                    : getIt.get<AppState>().getLanguageCode() == "ar"
                        ? 'CairoArabic'
                        : 'Poppins'),
            decorationColor: decorationColor ?? AppColors.errorColor),
      );

  Widget toText17({bool isEnglishOnly = false, Color? color, bool isBold = false, bool isCenter = false}) => Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        style: TextStyle(
            color: color ?? AppColors.blackColor,
            fontSize: 17.f,
            letterSpacing: -1,
            fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
            fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins'),
      );

  Widget toText18({
    Color? color,
    FontWeight? weight,
    bool isBold = false,
    bool isCenter = false,
    int? maxlines,
    TextOverflow? textOverflow,
    bool isEnglishOnly = false,
  }) =>
      Text(
        maxLines: maxlines,
        textAlign: isCenter ? TextAlign.center : null,
        this,
        overflow: textOverflow,
        style: TextStyle(
          fontSize: 18.f,
          fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
          color: color ?? AppColors.blackColor,
          letterSpacing: -0.4,
          fontFamily: (isEnglishOnly
              ? "Poppins"
              : getIt.get<AppState>().getLanguageCode() == "ar"
                  ? 'CairoArabic'
                  : 'Poppins'),
        ),
      );

  Widget toText19({Color? color, bool isBold = false}) => Text(
        this,
        style: TextStyle(
            fontSize: 19.f, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, color: color ?? AppColors.blackColor, letterSpacing: -0.4),
      );

  Widget toText20({
    Color? color,
    FontWeight? weight,
    bool isBold = false,
    bool isEnglishOnly = false,
  }) =>
      Text(
        this,
        style: TextStyle(
            fontFamily: (isEnglishOnly
                ? "Poppins"
                : getIt.get<AppState>().getLanguageCode() == "ar"
                    ? 'CairoArabic'
                    : 'Poppins'),
            fontSize: 20.f,
            fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
            color: color ?? AppColors.blackColor,
            letterSpacing: -0.4),
      );

  Widget toText21({Color? color, bool isBold = false, FontWeight? weight, int? maxlines}) => Text(
        this,
        maxLines: maxlines,
        style: TextStyle(
            color: color ?? AppColors.blackColor,
            fontSize: 21.f,
            letterSpacing: -1,
            fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal)),
      );

  Widget toText22({Color? color, bool isBold = false, bool isCenter = false}) => Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        style: TextStyle(
            height: 1,
            color: color ?? AppColors.blackColor,
            fontSize: 22.f,
            letterSpacing: -1,
            fontWeight: isBold ? FontWeight.bold : FontWeight.normal),
      );

  Widget toText24({
    Color? color,
    bool isBold = false,
    bool isCenter = false,
    FontWeight? fontWeight,
    double? letterSpacing,
    bool isEnglishOnly = false,
  }) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        style: TextStyle(
            fontFamily: (isEnglishOnly
                ? "Poppins"
                : getIt.get<AppState>().getLanguageCode() == "ar"
                    ? 'CairoArabic'
                    : 'Poppins'),
            height: 23 / 24,
            color: color ?? AppColors.blackColor,
            fontSize: 24.f,
            letterSpacing: letterSpacing ?? -1,
            fontWeight: isBold ? FontWeight.bold : fontWeight ?? FontWeight.normal),
      );

  Widget toText26({
    Color? color,
    bool isBold = false,
    double? height,
    bool isCenter = false,
    FontWeight? weight,
    double? letterSpacing,
    bool isEnglishOnly = false,
  }) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        style: TextStyle(
            fontFamily: (isEnglishOnly
                ? "Poppins"
                : getIt.get<AppState>().getLanguageCode() == "ar"
                    ? 'CairoArabic'
                    : 'Poppins'),
            height: height ?? 23 / 26,
            color: color ?? AppColors.blackColor,
            fontSize: 26.f,
            letterSpacing: letterSpacing ?? -1,
            fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal)),
      );

  Widget toText28({bool isEnglishOnly = false, Color? color, bool isBold = false, double? height, bool isCenter = false, double? letterSpacing}) =>
      Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        style: TextStyle(
            height: height ?? 23 / 28,
            color: color ?? AppColors.blackColor,
            fontSize: 28.f,
            letterSpacing: letterSpacing ?? -1,
            fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
            fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins'),
      );

  Widget toText32({bool isEnglishOnly = false, FontWeight? weight, Color? color, bool isBold = false, bool isCenter = false}) => Text(
        this,
        textAlign: isCenter ? TextAlign.center : null,
        style: TextStyle(
          height: getIt.get<AppState>().getLanguageCode() == "ar" ? 1.2 : 32 / 32,
          color: color ?? AppColors.blackColor,
          fontSize: 32.f,
          letterSpacing: -1,
          fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins',
          fontWeight: isBold ? FontWeight.bold : weight ?? FontWeight.normal,
        ),
      );

  Widget toText44({
    Color? color,
    bool isBold = false,
    bool isEnglishOnly = false,
  }) =>
      Text(
        this,
        style: TextStyle(
          height: 32 / 32,
          color: color ?? AppColors.blackColor,
          fontSize: 44.f,
          letterSpacing: -1,
          fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
          fontFamily: (isEnglishOnly
              ? "Poppins"
              : getIt.get<AppState>().getLanguageCode() == "ar"
                  ? 'CairoArabic'
                  : 'Poppins'),
        ),
      );

  Widget toSectionHeading({String upperHeading = "", String lowerHeading = ""}) {
    String upper = "";
    String lower = "";
    String heading = this;
    if (heading.isNotEmpty) {
      List<String> data = heading.split(" ");

      if (data.length > 1) {
        upper = data[0];
        data.removeAt(0);
        lower = data.join(" ");
      } else {
        lower = data[0];
      }
    }
    if (upperHeading.isNotEmpty) {
      upper = upperHeading;
    }
    if (lowerHeading.isNotEmpty) {
      lower = lowerHeading;
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisSize: MainAxisSize.min,
      children: [
        if (upper.isNotEmpty) upper.toText12(),
        lower.toText24(isBold: true),
      ],
    );
  }

  bool isValidEmail() {
    return RegExp(
            r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')
        .hasMatch(this);
  }

  String toFormattedDate() {
    String date = split("T")[0];
    String time = split("T")[1];
    var dates = date.split("-");
    return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a').format(DateFormat('hh:mm:ss').parse(time))}";
  }

  String getMonth(int month) {
    switch (month) {
      case 1:
        return "January";
      case 2:
        return "February";
      case 3:
        return "March";
      case 4:
        return "April";
      case 5:
        return "May";
      case 6:
        return "June";
      case 7:
        return "July";
      case 8:
        return "August";
      case 9:
        return "September";
      case 10:
        return "October";
      case 11:
        return "November";
      case 12:
        return "December";
      default:
        return "";
    }
  }

  String truncate(int max, {String suffix = ''}) {
    try {
      return length <= max ? this : '${substring(0, max - suffix.length)}$suffix';
    } catch (e) {
      return this;
    }
  }
}

extension DynamicTextStyleExtension on BuildContext {
  TextStyle dynamicTextStyle(
      {double? fontSize,
      FontWeight? fontWeight,
      Color? color,
      double? letterSpacing,
      double? wordSpacing,
      double? height,
      List<Shadow>? shadows,
      Color? backgroundColor,
      TextDecoration? decoration,
      Color? decorationColor,
      TextDecorationStyle? decorationStyle,
      double? decorationThickness,
      Locale? locale,
      TextBaseline? textBaseline,
      FontStyle? fontStyle,
      String? fontFamily,
      bool isLanguageSwitcher = false}) {
    AppState appState = getIt.get<AppState>();
    final family = appState.getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins';
    return TextStyle(
      fontFamily: fontFamily ?? family,
      fontSize: fontSize,
      fontWeight: fontWeight,
      color: color,
      letterSpacing: letterSpacing,
      wordSpacing: wordSpacing,
      height: height,
      shadows: shadows,
      backgroundColor: backgroundColor,
      decoration: decoration,
      decorationColor: decorationColor,
      decorationStyle: decorationStyle,
      decorationThickness: decorationThickness,
      locale: locale ?? Localizations.localeOf(this),
      textBaseline: textBaseline,
      fontStyle: fontStyle,
    );
  }
}

class FontUtils {
  /// Get the appropriate font family based on the current language
  static bool getFontFamily(BuildContext context) {
    // final projectViewModel = Provider.of<ProjectViewModel>(context, listen: false);
    return true;
  }

  /// Get the appropriate font family for a specific language
  static String getFontFamilyForLanguage(bool isArabic) {
    return isArabic ? 'CairoArabic' : 'Poppins';
  }
}

extension CountryExtension on CountryEnum {
  String get displayName {
    switch (this) {
      case CountryEnum.saudiArabia:
        return "Kingdom Of Saudi Arabia";
      case CountryEnum.unitedArabEmirates:
        return "United Arab Emirates";
      case CountryEnum.others:
        return "Others";
    }
  }

  String get nameArabic {
    switch (this) {
      case CountryEnum.saudiArabia:
        return "المملكة العربية السعودية";
      case CountryEnum.unitedArabEmirates:
        return "الإمارات العربية المتحدة";
      case CountryEnum.others:
        return "آخرون";
    }
  }

  String get iconPath {
    switch (this) {
      case CountryEnum.saudiArabia:
        return AppAssets.ksa;
      case CountryEnum.unitedArabEmirates:
        return AppAssets.uae;
      case CountryEnum.others:
        return AppAssets.globeOther;
    }
  }

  String get countryCode {
    switch (this) {
      case CountryEnum.saudiArabia:
        return "966";
      case CountryEnum.unitedArabEmirates:
        return "971";
      case CountryEnum.others:
        return "0";
    }
  }

  static CountryEnum fromDisplayName(String name) {
    switch (name) {
      case "Kingdom Of Saudi Arabia":
      case "المملكة العربية السعودية":
        return CountryEnum.saudiArabia;
      case "United Arab Emirates":
      case "الإمارات العربية المتحدة":
        return CountryEnum.unitedArabEmirates;
      case "Others":
      case "آخرون":
        return CountryEnum.others;
      default:
        throw Exception("Invalid country name");
    }
  }
}

extension GenderTypeExtension on GenderTypeEnum {
  String get value => this == GenderTypeEnum.male ? "M" : "F";

  String get type => this == GenderTypeEnum.male ? "Male" : "Female";

  String get typeAr => this == GenderTypeEnum.male ? "ذكر" : "أنثى";

  static GenderTypeEnum? fromValue(String? value) {
    switch (value) {
      case "M":
        return GenderTypeEnum.male;
      case "F":
        return GenderTypeEnum.female;
      default:
        return null;
    }
  }

  static GenderTypeEnum? fromType(String? type) {
    switch (type) {
      case "Male":
        return GenderTypeEnum.male;
      case "Female":
        return GenderTypeEnum.female;
      default:
        return null;
    }
  }
}

extension MaritalStatusTypeExtension on MaritalStatusTypeEnum {
  String get value {
    switch (this) {
      case MaritalStatusTypeEnum.single:
        return "U";
      case MaritalStatusTypeEnum.married:
        return "M";
      case MaritalStatusTypeEnum.divorced:
        return "D";
      case MaritalStatusTypeEnum.widowed:
        return "W";
    }
  }

  String get type {
    switch (this) {
      case MaritalStatusTypeEnum.single:
        return "Single";
      case MaritalStatusTypeEnum.married:
        return "Married";
      case MaritalStatusTypeEnum.divorced:
        return "Divorced";
      case MaritalStatusTypeEnum.widowed:
        return "Widowed";
    }
  }

  String get typeAr {
    switch (this) {
      case MaritalStatusTypeEnum.single:
        return "أعزب";
      case MaritalStatusTypeEnum.married:
        return "متزوج";
      case MaritalStatusTypeEnum.divorced:
        return "مطلق";
      case MaritalStatusTypeEnum.widowed:
        return "أرمل";
    }
  }

  static MaritalStatusTypeEnum? fromValue(String? value) {
    switch (value) {
      case "U":
        return MaritalStatusTypeEnum.single;
      case "M":
        return MaritalStatusTypeEnum.married;
      case "D":
        return MaritalStatusTypeEnum.divorced;
      case "W":
        return MaritalStatusTypeEnum.widowed;
      default:
        return null;
    }
  }

  static MaritalStatusTypeEnum? fromType(String? type) {
    switch (type) {
      case "Single":
        return MaritalStatusTypeEnum.single;
      case "Married":
        return MaritalStatusTypeEnum.married;
      case "Divorced":
        return MaritalStatusTypeEnum.divorced;
      case "Widowed":
        return MaritalStatusTypeEnum.widowed;
      default:
        return null;
    }
  }
}
