using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using Kendo.Mvc.UI;
using Kendo.Mvc.UI.Fluent;
using Kreta.Web.Security;

namespace Kreta.Web.Helpers
{
    public static class DateTimePickerExtensions
    {
        public static DateTimePickerBuilder KretaDateTimePicker(this HtmlHelper helper, string id, string className = "", bool enabled = true, string culture = "hu-HU", int interval = 1, DateTime? minValue = null, DateTime? maxValue = null, IDictionary<string, object> htmlAttributes = null)
        {
            if (helper.ViewData.ModelState[id] != null && helper.ViewData.ModelState[id].Errors.Count > 0)
                className = string.Format("{0} input-validation-error", className);

            var datetimepicker = helper.Kendo().DateTimePicker()
                .Name(id)
                .Enable(enabled)
                .Culture(culture)
                .Interval(interval);

            if (!string.IsNullOrWhiteSpace(className) || !string.IsNullOrWhiteSpace(id))
            {
                var attributes = new Dictionary<string, object>();
                if (!string.IsNullOrWhiteSpace(className))
                    attributes.Add("class", className.Trim());
                if (!string.IsNullOrWhiteSpace(id))
                    attributes.Add("id", id);

                datetimepicker.HtmlAttributes(attributes);
            }

            if (minValue.HasValue)
                datetimepicker.Min(minValue.Value);
            if (maxValue.HasValue)
                datetimepicker.Max(maxValue.Value);
            if (htmlAttributes != null)
                datetimepicker.HtmlAttributes(htmlAttributes);

            return datetimepicker;
        }

        public static DateTimePickerBuilder KretaDateTimePickerFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, IDictionary<string, object> htmlAttributes = null)
        {
            var fieldName = ExpressionHelper.GetExpressionText(expression);
            var fullBindingName = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
            var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            var value = metadata.Model;

            if (htmlAttributes == null)
                htmlAttributes = new Dictionary<string, object>();

            var validationAttributes = helper.GetUnobtrusiveValidationAttributes(fullBindingName, metadata);
            foreach (var key in validationAttributes.Keys)
            {
                if (key == "data-val-required")
                {
                    htmlAttributes.Add("title", validationAttributes[key].ToString());
                }
            }

            if (metadata.IsRequired)
            {
                htmlAttributes.Add("data-rule-required", "true");
                //htmlAttributes.Add("title", string.Format(StringResourcesUtil.GetString(3477), metadata.DisplayName));
                htmlAttributes.Add("data-labelmsg", metadata.DisplayName + " *");
            }
            else
            {
                htmlAttributes.Add("data-labelmsg", metadata.DisplayName);
            }

            var dateTimePicker = (expression.ReturnType == typeof(DateTime))
                ? helper.Kendo().DateTimePickerFor(Expression.Lambda<Func<TModel, DateTime>>(expression.Body, expression.Parameters))
                : helper.Kendo().DateTimePickerFor(Expression.Lambda<Func<TModel, DateTime?>>(expression.Body, expression.Parameters));

            dateTimePicker.HtmlAttributes(htmlAttributes);

            if (ClaimData.LCID == 1038 /*Magyar*/)
            {
                dateTimePicker.Format("yyyy. MM. dd. HH:mm");
            }

            return dateTimePicker;
        }

        public static MvcHtmlString RenderSearchPanel(this DateTimePickerBuilder helper, bool withMask = true)
        {
            string labelMsg = "";
            foreach (var item in helper.ToComponent().HtmlAttributes)
            {
                if (item.Key == "data-labelmsg" && item.Value != null)
                    labelMsg = item.Value.ToString();
            }

            StringBuilder sb = new StringBuilder();
            sb.Append("<div class=\"searchInputRowHeight\"><div>");
            sb.Append("<label class=\"searchPanelInputLabel\" for=\"").Append(helper.ToComponent().Name).Append("\">").Append(labelMsg).Append("</label>");
            sb.Append("</div><div>");
            sb.Append(helper.ToHtmlString());
            sb.Append("</div></div>");

            if (withMask)
                sb.Append("<script>$(\"#").Append(helper.ToComponent().Name.Replace('.', '_')).Append("\").kendoMaskedDateTimePicker();</script>");

            sb.Append("<script>$(\"#").Append(helper.ToComponent().Name.Replace('.', '_')).Append("\").change(function() { KretaDateTimeHelper.validateDateTime($(this)); });</script>");

            return new MvcHtmlString(sb.ToString());
        }

        public static MvcHtmlString RenderSearchPanelSideBar(this DateTimePickerBuilder helper, bool withMask = true)
        {
            string labelMsg = "";
            foreach (var item in helper.ToComponent().HtmlAttributes)
            {
                if (item.Key == "data-labelmsg" && item.Value != null)
                    labelMsg = item.Value.ToString();
            }

            StringBuilder sb = new StringBuilder();
            sb.Append("<div class=\"searchPanelRow\">");
            sb.Append("<div class=\"searchPanelRowTitle\">");
            sb.Append("<label class=\"searchPanelLabel\" for=\"").Append(helper.ToComponent().Name).Append("\">").Append(labelMsg).Append("</label>");
            sb.Append("</div>");
            sb.Append("<div class=\"searchPanelRowValue\">");
            sb.Append(helper.ToHtmlString());
            sb.Append("</div>");
            sb.Append("</div>");

            if (withMask)
                sb.Append("<script>$(\"#").Append(helper.ToComponent().Name.Replace('.', '_')).Append("\").kendoMaskedDateTimePicker();</script>");

            sb.Append("<script>$(\"#").Append(helper.ToComponent().Name.Replace('.', '_')).Append("\").change(function() { KretaDateTimeHelper.validateDateTime($(this)); });</script>");

            return new MvcHtmlString(sb.ToString());
        }

        public static MvcHtmlString RenderWithMask(this DateTimePickerBuilder helper)
        {
            var controlId = helper.ToComponent().Id;

            var output = new StringBuilder();
            output.Append(helper.ToHtmlString());
            output.Append("<script>");
            output.Append($"$(\"#{controlId}\").kendoMaskedDateTimePicker();");
            output.Append($"$(\"#{controlId}\").change(function() {{ KretaDateTimeHelper.validateDateTime($(this)); }});");
            output.Append("</script>");

            return new MvcHtmlString(output.ToString());
        }

        public static MvcHtmlString RenderWithName(this DateTimePickerBuilder helper, int labelWidth = 6, int inputWidth = 6, bool withMask = true, string tooltipResource = null)
        {
            string labelMsg = "";
            foreach (var item in helper.ToComponent().HtmlAttributes)
            {
                if (item.Key == "data-labelmsg" && item.Value != null)
                    labelMsg = item.Value.ToString();
            }

            var sb = new StringBuilder();

            if (string.IsNullOrWhiteSpace(tooltipResource))
                AddRenderWithNameBeginingFrame(sb, labelWidth, inputWidth, helper.ToComponent().Name, labelMsg);
            else
                AddRenderWithNameTooltipBeginingFrame(sb, labelWidth, inputWidth, helper.ToComponent().Name, labelMsg, tooltipResource);

            sb.Append(helper.ToHtmlString());
            AddRenderWithNameCloseingFrame(sb, withMask, helper.ToComponent().Name);

            return new MvcHtmlString(sb.ToString());
        }

        private static void AddRenderWithNameBeginingFrame(StringBuilder sb, int labelWidth, int inputWidth, string controlName, string labelMsg)
        {
            sb.AppendFormat("<div class=\"{0}\">", BootsrapHelper.GetSizeClasses(labelWidth));
            sb.AppendFormat("<label class=\"windowInputLabel\" for=\"{0} \">{1}</label>", controlName, labelMsg);
            sb.AppendFormat("</div><div class=\"{0} \">", BootsrapHelper.GetSizeClasses(inputWidth));
        }

        private static void AddRenderWithNameTooltipBeginingFrame(StringBuilder sb, int labelWidth, int inputWidth, string controlName, string labelMsg, string tooltipResource)
        {
            sb.AppendFormat("<div class=\"{0} kretaLabelTooltip \">", BootsrapHelper.GetSizeClasses(labelWidth));
            sb.AppendFormat("<label class=\"windowInputLabel\" for=\"{0} \">{1}", controlName, labelMsg);
            sb.Append("&nbsp;<img class='kretaLabelTooltipImg' />");
            sb.AppendFormat("<span class=\"kretaLabelTooltipText\">{0}</span>", tooltipResource);
            sb.Append("</label>");
            sb.AppendFormat("</div><div class=\"{0} \">", BootsrapHelper.GetSizeClasses(inputWidth));
        }

        private static void AddRenderWithNameCloseingFrame(StringBuilder sb, bool withMask, string controlName)
        {
            sb.Append("</div>");

            if (withMask)
                sb.AppendFormat("<script>$(\"#{0} \").kendoMaskedDateTimePicker();</script>", controlName.Replace('.', '_'));

            sb.Append("<script>$(\"#").Append(controlName.Replace('.', '_')).Append("\").change(function() { KretaDateTimeHelper.validateDateTime($(this)); });</script>");
        }

        public static MvcHtmlString RenderWithName(this DateTimePickerBuilder helper, string label, int labelWidth = 6, int inputWidth = 6, bool withMask = true, string tooltipResource = null)
        {
            var sb = new StringBuilder();

            if (string.IsNullOrWhiteSpace(tooltipResource))
                AddRenderWithNameBeginingFrame(sb, labelWidth, inputWidth, helper.ToComponent().Name, label);
            else
                AddRenderWithNameTooltipBeginingFrame(sb, labelWidth, inputWidth, helper.ToComponent().Name, label, tooltipResource);

            sb.Append(helper.ToHtmlString());
            AddRenderWithNameCloseingFrame(sb, withMask, helper.ToComponent().Name);

            return new MvcHtmlString(sb.ToString());
        }
    }
}