import 'package:device_calendar/device_calendar.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class DateUtil {
  /// convert String To Date function
  /// [date] String we want to convert
  static DateTime convertStringToDate(String? date) {
    if (date != null) {
      const start = "/Date(";
      const end = "+0300)";
      final startIndex = date.indexOf(start);
      final endIndex = date.indexOf(end, startIndex + start.length);
      return DateTime.fromMillisecondsSinceEpoch(int.parse(
        date.substring(startIndex + start.length, endIndex),
      ));
    } else
      return DateTime.now();
  }

  static DateTime convertStringToDateSaudiTimezone(String date, int projectId) {
    if (date != null) {
      const start = "/Date(";
      const end = "+0300)";
      final startIndex = date.indexOf(start);
      final endIndex = date.indexOf(end, startIndex + start.length);
      // if (projectId == 2 || projectId == 3) {
      //   return DateTime.fromMillisecondsSinceEpoch(
      //           int.parse(
      //             date.substring(startIndex + start.length, endIndex),
      //           ),
      //           isUtc: true)
      //       .add(Duration(hours: 4));
      // } else {
      return DateTime.fromMillisecondsSinceEpoch(
              int.parse(
                date.substring(startIndex + start.length, endIndex),
              ),
              isUtc: true)
          .add(Duration(hours: 3));
      // }
    } else
      return DateTime.now();
  }

  static DateTime convertStringToDateNoTimeZone(String date) {
    // /Date(1585774800000+0300)/
    if (date != null) {
      const start = "/Date(";
      const end = ")";
      final startIndex = date.indexOf(start);
      final endIndex = date.indexOf(end, startIndex + start.length);
      return DateTime.fromMillisecondsSinceEpoch(
        int.parse(
          date.substring(startIndex + start.length, endIndex),
        ),
      );
    } else
      return DateTime.now();
  }

  static DateTime convertStringToDateTime(String? date) {
    if (date != null) {
      try {
        var dateT = date.split('/');
        var year = dateT[2].substring(0, 4);
        var dateP = DateTime(int.parse(year), int.parse(dateT[1]), int.parse(dateT[0]));
        return dateP;
      } catch (e) {
        print(e);
      }

      return DateTime.now();
    } else
      return DateTime.now();
  }

  static String convertDateToString(DateTime date) {
    const start = "/Date(";
    const end = "+0300)/";
    int milliseconds = date.millisecondsSinceEpoch;

    return start + "$milliseconds" + end;
  }

  static String convertDateToStringLocation(DateTime date) {
    const start = "/Date(";
    const end = ")/";
    int milliseconds = date.millisecondsSinceEpoch;

    return start + "$milliseconds" + end;
  }

  static String convertTime(String timeStr) {
    TimeOfDay time = TimeOfDay(hour: int.parse(timeStr.split(":")[0]), minute: int.parse(timeStr.split(":")[1])); // 24-hour format time

    int hour = time.hourOfPeriod; // get hour in 12-hour format
    String meridiem = time.period == DayPeriod.am ? "AM" : "PM"; // get AM/PM

    String convertedTime = '$hour:${time.minute == 0 ? "00" : time.minute} $meridiem'; // create the new time string

    return convertedTime;
  }

  static String formatDateToDate(DateTime date, bool isArabic) {
    return DateFormat('dd MMM yyy', isArabic ? "ar_SA" : "en_US").format(date);
  }

  static String formatDateToTime(DateTime date) {
    return DateFormat('hh:mm a').format(date);
  }

  static String yearMonthDay(DateTime dateTime) {
    String dateFormat = '${dateTime.year}-${dateTime.month}-${dateTime.day}';
    return dateFormat;
  }

  static String time(DateTime dateTime) {
    String dateFormat = '${dateTime.hour}:${dateTime.minute}:00';
    return dateFormat;
  }

  static String convertDateMSToJsonDate(utc) {
    var dt = new DateTime.fromMicrosecondsSinceEpoch(utc);

    return "/Date(" + (dt.millisecondsSinceEpoch * 1000).toString() + '+0300' + ")/";
  }

  /// check Date
  /// [dateString] String we want to convert
  static String checkDate(DateTime checkedTime) {
    DateTime currentTime = DateTime.now();
    if ((currentTime.year == checkedTime.year) && (currentTime.month == checkedTime.month) && (currentTime.day == checkedTime.day)) {
      return "Today";
    } else if ((currentTime.year == checkedTime.year) && (currentTime.month == checkedTime.month)) {
      if ((currentTime.day - checkedTime.day) == 1) {
        return "YESTERDAY";
      } else if ((currentTime.day - checkedTime.day) == -1) {
        return "Tomorrow";
      }

      if ((currentTime.day - checkedTime.day) <= -2) {
        return "Next Week";
      } else {
        return "Old Date";
      }
    }
    return "Old Date";
  }

  static String getDateFormatted(String date) {
    DateTime dateObj = DateUtil.convertStringToDate(date);
    return DateUtil.getWeekDay(dateObj.weekday) + ", " + dateObj.day.toString() + " " + DateUtil.getMonth(dateObj.month) + " " + dateObj.year.toString();
  }

  static String getISODateFormat(DateTime dateTime) {
    // 2020-04-30T00:00:00.000
    return dateTime.toIso8601String();
  }

  /// get month by
  /// [month] convert month number in to month name
  static 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";
    }
  }

  /// get month by
  /// [month] convert month number in to month name in Arabic
  static getMonthArabic(int month) {
    switch (month) {
      case 1:
        return "يناير";
      case 2:
        return " فبراير";
      case 3:
        return "مارس";
      case 4:
        return "أبريل";
      case 5:
        return "مايو";
      case 6:
        return "يونيو";
      case 7:
        return "يوليو";
      case 8:
        return "أغسطس";
      case 9:
        return "سبتمبر";
      case 10:
        return " اكتوبر";
      case 11:
        return " نوفمبر";
      case 12:
        return "ديسمبر";
    }
  }

  static getMonthByName(String month) {
    switch (month.toLowerCase()) {
      case 'january':
        return 1;
      case 'february':
        return 2;
      case 'march':
        return 3;
      case 'april':
        return 4;
      case 'may':
        return 5;
      case 'june':
        return 6;
      case 'july':
        return 7;
      case 'august':
        return 8;
      case 'september':
        return 9;
      case 'october':
        return 10;
      case 'november':
        return 11;
      case 'december':
        return 12;
    }
  }

  static getMonthDateTime(String month, yearName) {
    DateTime? date;
    try {
      date = DateTime(int.parse(yearName), getMonthByName(month));
    } catch (e) {
      print(e);
    }
    return date ?? DateTime.now();
  }

  /// get month by
  /// [weekDay] convert week day in int to week day name
  static getWeekDay(int weekDay) {
    switch (weekDay) {
      case 1:
        return "Monday";
      case 2:
        return "Tuesday";
      case 3:
        return "Wednesday";
      case 4:
        return "Thursday";
      case 5:
        return "Friday";
      case 6:
        return "Saturday ";
      case 7:
        return "Sunday";
    }
  }

  /// get month by
  /// [weekDay] convert week day in int to week day name arabic
  static getWeekDayArabic(int weekDay) {
    switch (weekDay) {
      case 1:
        return "الاثنين";
      case 2:
        return "الثلاثاء";
      case 3:
        return "الاربعاء";
      case 4:
        return "الخميس";
      case 5:
        return "الجمعه";
      case 6:
        return "السبت ";
      case 7:
        return "الاحد";
    }
  }

  static getWeekDayEnglish(int weekDay) {
    switch (weekDay) {
      case 1:
        return "Monday";
      case 2:
        return "Tuesday";
      case 3:
        return "Wednesday";
      case 4:
        return "Thursday";
      case 5:
        return "Friday";
      case 6:
        return "Saturday ";
      case 7:
        return "Sunday";
    }
  }

  /// get data formatted like Apr 26,2020
  /// [dateTime] convert DateTime to data formatted
  static String getMonthDayYearDateFormatted(DateTime dateTime) {
    if (dateTime != null)
      return getMonth(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString();
    else
      return "";
  }

  /// get data formatted like Apr 26,2020
  /// [dateTime] convert DateTime to data formatted Arabic
  static String getMonthDayYearDateFormattedAr(DateTime dateTime) {
    if (dateTime != null)
      return getMonthArabic(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString();
    else
      return "";
  }

  /// get data formatted like Thursday, Apr 26,2020
  /// [dateTime] convert DateTime to date formatted
  static String getWeekDayMonthDayYearDateFormatted(DateTime dateTime, String lang) {
    if (dateTime != null)
      return lang == 'en'
          ? getWeekDayEnglish(dateTime.weekday) + ", " + getMonth(dateTime.month) + " " + dateTime.day.toString() + " " + dateTime.year.toString()
          : getWeekDayArabic(dateTime.weekday) + ", " + dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
    else
      return "";
  }

  static String getMonthDayYearLangDateFormatted(DateTime dateTime, String lang) {
    if (dateTime != null)
      return lang == 'en'
          ? getMonth(dateTime.month) + " " + dateTime.day.toString() + " " + dateTime.year.toString()
          : dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
    else
      return "";
  }

  /// get data  formatted like 26/4/2020
  static String getDayMonthYearLangDateFormatted(DateTime dateTime, String lang) {
    if (dateTime != null)
      return lang == 'en'
          ? dateTime.day.toString() + " " + getMonth(dateTime.month) + " " + dateTime.year.toString()
          : dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
    else
      return "";
  }

  static String getMonthYearLangDateFormatted(DateTime dateTime, String lang) {
    if (dateTime != null)
      return lang == 'en' ? getMonth(dateTime.month) + " " + dateTime.year.toString() : getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
    else
      return "";
  }

  /// get data  formatted like 26/4/2020
  /// [dateTime] convert DateTime to data formatted
  static String getDayMonthYearDateFormatted(DateTime dateTime) {
    if (dateTime != null)
      return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString();
    else
      return "";
  }

  /// get data  formatted like 26/4/2020
  /// [dateTime] convert DateTime to data formatted
  static String getDayMonthDateFormatted(DateTime dateTime) {
    if (dateTime != null)
      return DateFormat('dd/MM').format(dateTime);
    else
      return "";
  }

  /// get data  formatted like 26/4/2020
  /// [dateTime] convert DateTime to data formatted according to language
  static String getDayMonthYearDateFormattedLang(DateTime dateTime, bool isArabic) {
    if (dateTime != null)
      return DateFormat('dd/MM/yyyy', isArabic ? "ar_SA" : "en_US").format(dateTime);
    else
      return "";
  }

  /// get data  formatted like 10:30 according to lang
  static String formatDateToTimeLang(DateTime date, bool isArabic) {
    return DateFormat('HH:mm', isArabic ? "ar_SA" : "en_US").format(date);
  }

  /// get data  formatted like 26/4/2020 10:30
  /// [dateTime] convert DateTime to data formatted
  static String getDayMonthYearHourMinuteDateFormatted(DateTime dateTime) {
    if (dateTime != null)
      return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString() + " " + DateFormat('HH:mm').format(dateTime);
    else
      return "";
  }

  /// get data  formatted like 2020-8-13 09:43:00
  /// [dateTime] convert DateTime to data formatted
  static String getYearMonthDayHourMinSecDateFormatted(DateTime dateTime) {
    if (dateTime != null)
      return dateTime.year.toString() +
          "-" +
          dateTime.month.toString() +
          "-" +
          dateTime.day.toString() +
          " " +
          dateTime.hour.toString() +
          ":" +
          dateTime.minute.toString() +
          ":" +
          dateTime.second.toString();
    else
      return "";
  }

  static String getFormattedDate(DateTime dateTime, String formattedString) {
    return DateFormat(formattedString).format(dateTime);
  }

  static convertISODateToJsonDate(String isoDate) {
    return "/Date(" + DateFormat('mm-dd-yyy').parse(isoDate).millisecondsSinceEpoch.toString() + ")/";
  }

  static String getDay(DayOfWeek dayOfWeek) {
    switch (dayOfWeek) {
      case DayOfWeek.Monday:
        return "Monday";
        break;
      case DayOfWeek.Tuesday:
        return "Tuesday";
        break;
      case DayOfWeek.Wednesday:
        return "Wednesday";
        break;
      case DayOfWeek.Thursday:
        return "Thursday";
        break;
      case DayOfWeek.Friday:
        return "Friday";
        break;
      case DayOfWeek.Saturday:
        return "Saturday";
        break;
      case DayOfWeek.Sunday:
        return "Sunday";
        break;
    }
    return "";
  }
}
