using System;
using System.Globalization;

namespace Sevomin.Models.Helpers
{
    public class DateAssist
    {
        public class FromToDate
        {
            public DateTime Start;
            public DateTime End;
            public string startShamsi;
            public string endShamsi;
        }

        /// <summary>
        /// None Zero-Based month number
        /// </summary>
        /// <param name="monthNumber"></param>
        /// <returns></returns>
        public static string GetPersianMonthName(int monthNumber)
        {
            switch (monthNumber)
            {
                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 "اسفند";
                default:
                    throw new ArgumentException("شماره ماه باید بین 1 تا 12 باشد.", "monthNumber", null);
            }
        }

        public static string GetFullPersianDate(DateTime value)
        {
            PersianCalendar pc = new PersianCalendar();
            return string.Format("{0} {1} {2}",
                             pc.GetDayOfMonth(value), GetPersianMonthName(pc.GetMonth(value)),
                             pc.GetYear(value));
        }

        public static DateTime? ValidateAndSetToMiladi(string value, DateTime? defaultValue = null)
        {
            string vd = ValidateDate(value);
            if (string.IsNullOrEmpty(vd))
                return defaultValue;
            return ToMiladi(vd);
        }

        public static DateTime ToMiladi(string value)
        {
            if (value == "" || value == null)
                return DateTime.MinValue;
            PersianCalendar pc = new PersianCalendar();
            DateTime mil;
            mil = pc.ToDateTime(int.Parse(value.Substring(0, 4)),
                int.Parse(value.Substring(5, 2)), int.Parse(value.Substring(8, 2))
                , 0, 0, 0, 0);
            return mil;
        }

        public static string ToShamsi(DateTime value)
        {
            if (value == DateTime.MinValue)
                return string.Empty;
            PersianCalendar pc = new PersianCalendar();
            return string.Format("{0:0000}/{1:00}/{2:00}",
                             pc.GetYear(value), pc.GetMonth(value),
                             pc.GetDayOfMonth(value));
        }

        public static string ValidateDate(string value)
        {
            if (value == null)
                return "";
            int offset = 0;
            if (value.Length == 8) //13801010
            {
                value = value.Insert(4, "/");
                value = value.Insert(7, "/");
            }
            if (int.TryParse(value, out offset))
            {
                if (offset > 500 || offset < -500)
                    return "";
                return ToShamsi(DateTime.Today.AddDays(offset));
            }
            else
            {
                try
                {
                    DateTime val = ToMiladi(value);
                    if (val < DateTime.Today.AddYears(-5) ||
                        val > DateTime.Today.AddYears(10))
                        return "";
                    return value;
                }
                catch (Exception)
                {
                    return "";
                }
            }
        }

        public static FromToDate GetThisMonth()
        {
            PersianCalendar pc = new PersianCalendar();
            DateTime value = DateTime.Today;
            return GetMonth(pc.GetMonth(value));
        }

        /// <summary>
        /// returns date of 1st and last day of month as a
        /// FromToDate object
        /// </summary>
        /// <param name="monthIndex">Index of Mounth 1-based</param>
        /// <returns>FromToDate object</returns>
        public static FromToDate GetMonth(int monthIndex)
        {
            PersianCalendar pc = new PersianCalendar();
            FromToDate ftd = new FromToDate();
            DateTime value = DateTime.Today;
            string startShamsi = string.Format("{0:0000}/{1:00}/{2:00}",
                                         pc.GetYear(value), monthIndex,
                                         1);
            string endShamsi = string.Format("{0:0000}/{1:00}/{2:00}",
                             pc.GetYear(value), monthIndex,
                             pc.GetDaysInMonth(pc.GetYear(value), monthIndex));
            ftd.Start = ToMiladi(startShamsi);
            ftd.End = ToMiladi(endShamsi);
            ftd.startShamsi = startShamsi;
            ftd.endShamsi = endShamsi;
            return ftd;
        }

        public static String NextMonth(string currentDate, int dayOfMonth)
        {
            return NextMonth(currentDate, dayOfMonth, 1);
        }
        public static String NextMonth(string currentDate, int dayOfMonth, int monthInterval)
        {
            try
            {
                PersianCalendar pc = new PersianCalendar();
                int year = int.Parse(currentDate.Substring(0, 4));
                int month = int.Parse(currentDate.Substring(5, 2));
                month += monthInterval;
                if (month > 12)
                {
                    year += 1;
                    month = 1;
                }
                if (pc.GetDaysInMonth(year, month) < dayOfMonth)
                    dayOfMonth = pc.GetDaysInMonth(year, month);
                return string.Format("{0:0000}/{1:00}/{2:00}", year, month, dayOfMonth);

            }
            catch (Exception)
            {
                return "";
            }

        }

        public static string ToPersianNumbers(string number)
        {
            char[] temp = new char[number.Length];

            for (int i = 0; i < number.Length; i++)
            {
                char value = number[i];

                if (value >= 48 && value <= 57)
                    temp[i] = (char)(value + 1728);
                else
                    temp[i] = value;
            }

            return new String(temp);
        }

        public static int GetJalaliWeekNumber(DateTime gregorianDate)
        {
            PersianCalendar pc = new PersianCalendar();

            DateTime gregYearStart = pc.ToDateTime(pc.GetYear(gregorianDate), 1, 1, 0, 0, 0, 0);
            int diff = (gregorianDate - gregYearStart).Days;
            int wd = ((int)pc.GetDayOfWeek(gregorianDate) + 2) % 7;

            return (diff - wd + 10) / 7;
        }
    }
}