using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Routing;
using Vrh.OneReport.Lib.Areas.OneReport.Helpers;

namespace Vrh.OneReport
{
    public static class StringExtensions
    {
        /// <summary>
        /// An extension method that extends string to replace multiple strings provided in a dictionary.
        /// The strings to be replaced are the keys of the dictionary prefixed by the given prefix and 
        /// postfixed by the given postfix string (if any).
        /// </summary>
        /// <param name="str">The string to be used.</param>
        /// <param name="replace">The string pairs to be replaced.</param>
        /// <param name="prefix">The prefix string used in front of the key string.</param>
        /// <param name="postfix">The postfix string used after the key string.</param>
        /// <returns>The result of the process.</returns>
        public static string Replace(this String str, Dictionary<string, string> replace, string prefix = null, string postfix = null)
        {
            string result = str;

            if (!String.IsNullOrWhiteSpace(result) && replace != null && replace.Count > 0)
            {
                foreach (var item in replace) result = result.Replace(String.Concat(prefix, item.Key, postfix), item.Value);
            }

            return result;
        }

        /// <summary>
        /// Kicseréli a megfelelő dátumra a @DAYSBACK kifejezéseket a stringben
        /// </summary>
        /// <param name="str">bemenpő string</param>
        /// <returns>kimenő string</returns>
        public static string ApplyDaysback(this String str)
        {
            //str = str.ToUpper();
            int startPos = str.IndexOf(DAYSBACK_KEYSTR);
            if (startPos > -1)
            {
                int endPos = str.IndexOf(Constants.NameSeparator, startPos + 1);
                if (endPos > -1)
                {
                    string daysStr = str.Substring(startPos + DAYSBACK_KEYSTR.Length, endPos - (startPos + DAYSBACK_KEYSTR.Length));
                    if (Int32.TryParse(daysStr, out int days))
                    {
                        DateTime baseDate = DateTime.Today;
                        baseDate = baseDate.AddDays(-days);
                        string newStr = baseDate.ToString("yyyyMMdd");
                        str = str.Replace(DAYSBACK_KEYSTR + daysStr + Constants.NameSeparator, newStr);
                    }
                }
            }
            return str;
        }
        private const string DAYSBACK_KEYSTR = Constants.NameSeparator + "DAYSBACK";

        /// <summary>
        /// Kicseréli a megfelkelő dátumra a @WEEKSBACK kifejezéseket a stringben
        /// </summary>
        /// <param name="str">bemenpő string</param>
        /// <returns>kimenő string</returns>
        public static string ApplyWeeksback(this String str)
        {
            //str = str.ToUpper();
            int startPos = str.IndexOf(WEEKSBACK_KEYSTR);
            if (startPos > -1)
            {
                int endPos = str.IndexOf(Constants.NameSeparator, startPos + 1);
                if (endPos > -1)
                {
                    string weeksStr = str.Substring(startPos + WEEKSBACK_KEYSTR.Length, endPos - (startPos + WEEKSBACK_KEYSTR.Length));
                    if (Int32.TryParse(weeksStr, out int weeks))
                    {
                        DateTime baseDate = DateTime.Today;
                        baseDate = baseDate.AddDays(-weeks * 7);
                        string newStr = baseDate.ToString("yyyyMMdd");
                        str = str.Replace(WEEKSBACK_KEYSTR + weeksStr + Constants.NameSeparator, newStr);
                    }
                }
            }
            return str;
        }
        private const string WEEKSBACK_KEYSTR = Constants.NameSeparator + "WEEKSBACK";

        /// <summary>
        /// Kicseréli a megfelkelő dátumra a @WEEKSBACK kifejezéseket a stringben
        /// </summary>
        /// <param name="str">bemenpő string</param>
        /// <returns>kimenő string</returns>
        public static string ApplyMonthsback(this String str)
        {
            //str = str.ToUpper();
            int startPos = str.IndexOf(MONTHSBACK_KEYSTR);
            if (startPos > -1)
            {
                int endPos = str.IndexOf(Constants.NameSeparator, startPos + 1);
                if (endPos > -1)
                {
                    string monthsStr = str.Substring(startPos + MONTHSBACK_KEYSTR.Length, endPos - (startPos + MONTHSBACK_KEYSTR.Length));
                    if (Int32.TryParse(monthsStr, out int months))
                    {
                        DateTime baseDate = DateTime.Today;
                        baseDate = baseDate.AddMonths(-months);
                        string newStr = baseDate.ToString("yyyyMMdd");
                        str = str.Replace(MONTHSBACK_KEYSTR + monthsStr + Constants.NameSeparator, newStr);
                    }
                }
            }
            return str;
        }
        private const string MONTHSBACK_KEYSTR = Constants.NameSeparator + "MONTHSBACK";

    }

    public static class RouteValueDictionaryExtensions
    {
        public static RouteValueDictionary AddQueryStringParameters(this RouteValueDictionary dict)
        {
            var querystring = HttpContext.Current.Request.QueryString;

            foreach (var key in querystring.AllKeys)
            {
                if (!dict.ContainsKey(key))
                {
                    dict.Add(key, querystring.GetValues(key)[0]);
                }
            }

            return dict;
        }
    }
}

namespace System.Web.Mvc.Html
{
    public static class HtmlHelperExtensions
    {
        /// <summary>
        /// Returns the Log messages.
        /// <param name="html">The HTML object.</param>
        /// <return>The log messages.</returns>
        /// </summary>
        public static MvcHtmlString LogMessages(this HtmlHelper html)
        {
            return new MvcHtmlString(Log.GetHtmlMessages());
        }

        public static MvcHtmlString Button(this HtmlHelper helper, string text,
                                           IDictionary<string, object> htmlAttributes = null)
        {
            var builder = new TagBuilder("button");
            builder.InnerHtml = text;
            if (htmlAttributes != null)
                builder.MergeAttributes(htmlAttributes);
            return MvcHtmlString.Create(builder.ToString());
        }

        public static MvcHtmlString Button(this HtmlHelper helper, string text, string title,
                                           IDictionary<string, object> htmlAttributes = null)
        {
            var builder = new TagBuilder("button");
            builder.InnerHtml = text;
            if (htmlAttributes != null)
                builder.MergeAttributes(htmlAttributes);
            if (!string.IsNullOrEmpty(title))
                builder.MergeAttribute("title", title);

            return MvcHtmlString.Create(builder.ToString());
        }

        public static MvcHtmlString ImageButton(this HtmlHelper helper, string src,
                                               IDictionary<string, object> htmlAttributes = null)
        {
            var builder = new TagBuilder("input");
            if (htmlAttributes != null)
                builder.MergeAttributes(htmlAttributes);
            builder.MergeAttribute("type", "image");
            builder.MergeAttribute("src", src);

            return MvcHtmlString.Create(builder.ToString());
        }

        public static MvcHtmlString ImageButton(this HtmlHelper helper, string src, string title,
                                           IDictionary<string, object> htmlAttributes = null)
        {
            var builder = new TagBuilder("input");
            if (htmlAttributes != null)
                builder.MergeAttributes(htmlAttributes);
            builder.MergeAttribute("type", "image");
            builder.MergeAttribute("src", src);
            if (!string.IsNullOrEmpty(title))
                builder.MergeAttribute("title", title);

            return MvcHtmlString.Create(builder.ToString());
        }

        public static MvcHtmlString ImageButton(this HtmlHelper helper, string src, string alt, string title,
                                           IDictionary<string, object> htmlAttributes = null)
        {
            var builder = new TagBuilder("input");
            if (htmlAttributes != null)
                builder.MergeAttributes(htmlAttributes);
            builder.MergeAttribute("type", "image");
            builder.MergeAttribute("src", src);
            if (!string.IsNullOrEmpty(title))
                builder.MergeAttribute("title", title);
            if (!string.IsNullOrEmpty(alt))
                builder.MergeAttribute("alt", alt);

            return MvcHtmlString.Create(builder.ToString());
        }

        public static MvcHtmlString TextAreaAutoSize(this HtmlHelper htmlHelper, string text, IDictionary<string, object> htmlAttributes = null)
        {
            int width = htmlAttributes == null || !htmlAttributes.ContainsKey("cols") ? 85 : (int)htmlAttributes["cols"];
            var lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)
                            .Aggregate(0, (total, next) => total += (next.Length <= width ? 1 : (int)Math.Ceiling((double)next.Length / width)));
            var attributes = new RouteValueDictionary(htmlAttributes);
            //attributes["style"] = string.Format("width:{0}em; height:{1}em;", width, lines);
            attributes["rows"] = lines;
            attributes["cols"] = width;

            return htmlHelper.TextArea(text, attributes);
        }
    }
}