import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/exceptions/api_exception.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:mohem_flutter_app/widgets/loading_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';
// ignore_for_file: avoid_annotating_with_dynamic

class Utils {
  static bool _isLoadingVisible = false;

  static bool get isLoading => _isLoadingVisible;

  static void showToast(String message, {bool longDuration = true}) {
    Fluttertoast.showToast(
        msg: message,
        toastLength: longDuration ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
        timeInSecForIosWeb: 1,
        backgroundColor: Colors.black54,
        textColor: Colors.white,
        fontSize: 16.0);
  }

  static dynamic getNotNullValue(List<dynamic> list, int index) {
    try {
      return list[index];
    } catch (ex) {
      return null;
    }
  }

  static int stringToHex(String colorCode) {
    try {
      return int.parse(colorCode.replaceAll("#", "0xff"));
    } catch (ex) {
      return (0xff000000);
    }
  }

  static Future delay(int millis) async {
    return await Future.delayed(Duration(milliseconds: millis));
  }

  static void showLoading(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _isLoadingVisible = true;
      showDialog(
        context: context,
        barrierColor: Colors.black.withOpacity(0.5),
        builder: (BuildContext context) => LoadingDialog(),
      ).then((value) {
        _isLoadingVisible = false;
      });
    });
  }

  static void hideLoading(BuildContext context) {
    if (_isLoadingVisible) {
      _isLoadingVisible = false;
      Navigator.of(context).pop();
    }
    _isLoadingVisible = false;
  }

  static Future<String> getStringFromPrefs(String key) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getString(key) ?? "";
  }

  static Future<bool> saveStringFromPrefs(String key, String value) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return await prefs.setString(key, value);
  }

  static void handleException(dynamic exception, cxt, Function(String)? onErrorMessage) {
    String errorMessage;
    if (exception is APIException) {
      if (exception.message == APIException.UNAUTHORIZED) {
        return;
      } else {
        errorMessage = exception.error?.errorMessage ?? exception.message;
      }
    } else {
      errorMessage = APIException.UNKNOWN;
    }
    if (onErrorMessage != null) {
      onErrorMessage(errorMessage);
    } else {
      if (!AppState().isAuthenticated) {
        showDialog(
          context: cxt,
          builder: (cxt) => ConfirmDialog(
            message: errorMessage,
            onTap: () {
              Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route<dynamic> route) => false);
            },
          ),
        );
      } else {
        showToast(errorMessage);
      }
    }
  }

  static void confirmDialog(cxt, String message) {
    showDialog(
      context: cxt,
      builder: (cxt) => ConfirmDialog(
        message: message,
      ),
    );
  }

  static Widget getNoDataWidget(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0),
        LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15),
      ],
    ).center;
  }

  static Widget getNoChatWidget(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0),
        LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15),
      ],
    ).center;
  }

  static Uint8List getPostBytes(img) {
    try {
      var b64 = img.replaceFirst('data:image/png;base64,', '');
      if (img != null && Utils.isBase64(b64)) return Utils.dataFromBase64String(b64);
    } catch (e) {}
    return Uint8List.fromList([]);
  }

  static String getBase64FromJpeg(img) {
    try {
      var b64 = img.replaceFirst('data:image/jpeg;base64,', '');
      return b64;
    } catch (e) {}
    return "";
  }

  static bool isBase64(String str) {
    RegExp _base64 = RegExp(r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$');
    return _base64.hasMatch(str);
  }

  static Uint8List dataFromBase64String(String base64String) {
    return base64Decode(base64String);
  }

  static Widget tableColumnTitle(String? text, {bool showDivider = true, bool alignCenter = false}) {
    text ??= "";
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisSize: MainAxisSize.min,
      children: [
        6.height,
        alignCenter ? text.toText12().center : text.toText12(),
        5.height,
        if (showDivider)
          const Divider(
            height: 1,
            color: Color(0xff2E303A),
            thickness: 1,
          )
      ],
    );
  }

  static Decoration containerRadius(Color background, double radius) {
    return BoxDecoration(
      color: background,
      border: Border.all(
          width: 1, //
          color: background //                  <--- border width here
          ),
      borderRadius: BorderRadius.circular(radius),
    );
  }

  static Widget mHeight(double h) {
    return Container(
      height: h,
    );
  }

  static Widget mDivider(Color color) {
    return Divider(
      // width: double.infinity,
      height: 1,
      color: color,
    );
  }

  static Widget tableColumnValue(String text, {bool isCapitable = true, bool alignCenter = false}) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisSize: MainAxisSize.min,
      children: [
        12.height,
        if (alignCenter)
          (isCapitable ? text.toLowerCase().capitalizeFirstofEach : text).toText12(color: MyColors.normalTextColor).center
        else
          (isCapitable ? text.toLowerCase().capitalizeFirstofEach : text).toText12(color: MyColors.normalTextColor),
        12.height,
      ],
    );
  }

  /// EIT Forms date formats

  static String getMonthNamedFormat(DateTime date) {
    /// it will return like "29-Sep-2022"
    return DateFormat('dd-MMM-yyyy').format(date);
  }

  static String reverseFormatDate(String date) {
    String formattedDate;
    if (date.isNotEmpty) {
      formattedDate = date.replaceAll('/', '-');
      formattedDate = formattedDate.replaceAll(' 00:00:00', '');
    } else {
      formattedDate = date;
    }
    return formattedDate;
  }

  static String formatStandardDate(String date) {
    String formattedDate;
    if (date.isNotEmpty) {
      formattedDate = date.replaceAll('-', '/');
    } else {
      formattedDate = date;
    }
    return formattedDate;
  }

  static String reverseFormatStandardDate(String date) {
    String formattedDate;
    if (date.isNotEmpty) {
      formattedDate = date.replaceAll('/', '-');
    } else {
      formattedDate = date;
    }
    return formattedDate;
  }

  static String formatDate(String date) {
    String formattedDate;

    if (date.isNotEmpty) {
      date = date.substring(0, 10);
      formattedDate = date.replaceAll('-', '/');
      formattedDate = formattedDate + ' 00:00:00';
    } else {
      formattedDate = date;
    }
    return formattedDate;
  }

  static String formatDateNew(String date) {
    String formattedDate;
    if (date.isNotEmpty) {
      formattedDate = date.split('T')[0];
      formattedDate = formattedDate + ' 00:00:00';
    } else {
      formattedDate = date;
    }
    return formattedDate;
  }

  static Future<DateTime> selectDate(BuildContext context, DateTime selectedDate) async {
    if (!Platform.isIOS) {
      await showCupertinoModalPopup(
        context: context,
        builder: (cxt) => Container(
          height: 250,
          color: Colors.white,
          child: CupertinoDatePicker(
            backgroundColor: Colors.white,
            mode: CupertinoDatePickerMode.date,
            onDateTimeChanged: (value) {
              if (value != null && value != selectedDate) {
                selectedDate = value;
              }
            },
            initialDateTime: selectedDate,
          ),
        ),
      );
    } else {
      DateTime? picked = await showDatePicker(context: context, initialDate: selectedDate, initialEntryMode: DatePickerEntryMode.calendarOnly, firstDate: DateTime(2015, 8), lastDate: DateTime(2101));
      if (picked != null && picked != selectedDate) {
        selectedDate = picked;
      }
    }
    return selectedDate;
  }
}
