using CloudBuilder;
using CloudBuilder.Gui;
using CloudBuilder.Gui.DependencyInjection;
using Krypton.Toolkit;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Krypton.Toolkit
{
    public static class KryptonDateTimePickerExtensions
    {
        public const string DATA_FROMAT = "yyyy-MM-dd";

        public static ExFormSnapshotEntry GetExFormSnapshotEntry(this KryptonDateTimePicker kryptonDateTimePicker)
        {
            string bindDataName = null;

            if (GetProvider().GetCustomAttribute(kryptonDateTimePicker) != null)
                bindDataName = GetProvider().GetCustomAttribute(kryptonDateTimePicker).BindDataName;

            return new ExFormSnapshotEntry(
                kryptonDateTimePicker.Name,
                bindDataName,
                kryptonDateTimePicker.Text,
                kryptonDateTimePicker.Text);
        }

        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker,
            BindingContextCustomAttribute bindingContext)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, bindingContext);
        }

        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker,
            EnumEditModeColor editModeColor)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, editModeColor);
        }
        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker, EnumEditModeColor editModeColor, string bindDisplayName)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, editModeColor, bindDisplayName);
        }

        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker,
           string bindDataName,
           EnumEditModeColor editModeColor)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, bindDataName, editModeColor);
        }

        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker,
          string bindDataName,
          string bindFormat,
          EnumEditModeColor editModeColor)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, bindDataName, bindFormat, editModeColor);
        }


        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker,
            string bindDataName)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, bindDataName, EnumBindDirection.Both);
        }

        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker,
            string bindDataName,
            EnumBindDirection bindDirection)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, bindDataName, bindDirection);
        }


        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker,
            string bindDataName,
            EnumBindDirection bindDirection,
            EnumEditModeColor editModeColor)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, bindDataName, bindDirection, editModeColor);
        }

        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker,
            string bindDataName,
            string bindFormat,
            EnumBindDirection bindDirection)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, bindDataName, bindFormat, bindDirection);
        }

        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker,
           string permissionName,
           Operate permissionMode)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, permissionName, permissionMode);
        }

        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker, string permissionName, string dependentDetailName, Operate permissionMode)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, permissionName, dependentDetailName, permissionMode);
        }

        public static void Set(this KryptonDateTimePicker kryptonDateTimePicker, string permissionName, string dependentDetailName)
        {
            GetProvider().SetCustomAttribute(kryptonDateTimePicker, permissionName, dependentDetailName);
        }

        public static string GetValue(this KryptonDateTimePicker kryptonDateTimePicker)
        {
            if (!kryptonDateTimePicker.Checked) return null!;
            return kryptonDateTimePicker.Text;
        }

        public static Nullable<DateTime> GetDateTimeValue(this KryptonDateTimePicker kryptonDateTimePicker)
        {
            string bindFormat = DATA_FROMAT;

            if (!string.IsNullOrEmpty(kryptonDateTimePicker.CustomFormat))
                bindFormat = kryptonDateTimePicker.CustomFormat;

            if (GetProvider().GetCustomAttribute(kryptonDateTimePicker) != null &&
                 !string.IsNullOrEmpty(GetProvider().GetCustomAttribute(kryptonDateTimePicker).BindFormat))
            {
                bindFormat = GetProvider().GetCustomAttribute(kryptonDateTimePicker).BindFormat;
            }

            if (kryptonDateTimePicker.Checked)
                return DateTime.ParseExact(kryptonDateTimePicker.Text.Trim(), bindFormat, CultureInfo.InvariantCulture, DateTimeStyles.None);
            return null;
        }

        public static void SetValue(this KryptonDateTimePicker kryptonDateTimePicker, string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                kryptonDateTimePicker.Checked = false;
                return;
            }
            kryptonDateTimePicker.Checked = true;
            kryptonDateTimePicker.Text = value;
        }

        public static void SetValue(this KryptonDateTimePicker kryptonDateTimePicker, object value, string bindFormat)
        {
            if (value == null)
            {
                kryptonDateTimePicker.Checked = false;
            }
            else if (value is string)
            {
                if (string.IsNullOrEmpty((string)value))
                {
                    kryptonDateTimePicker.Checked = false;
                    return;
                }
                kryptonDateTimePicker.Checked = true;
                kryptonDateTimePicker.Value = DateTime.ParseExact(value.ToString(), bindFormat, CultureInfo.InvariantCulture, DateTimeStyles.None);
            }
            else if (value is DateTime)
            {
                kryptonDateTimePicker.Checked = true;
                if (value == null || ((DateTime)value).Year == 1)
                    kryptonDateTimePicker.Checked = false;
                else if (!string.IsNullOrEmpty(bindFormat))
                {
                    kryptonDateTimePicker.Checked = false;
                }
                else
                    kryptonDateTimePicker.Value = (DateTime)value;
            }
            else if (value is SqlDateTime)
            {
                kryptonDateTimePicker.Checked = true;
                if (((SqlDateTime)value).IsNull || ((SqlDateTime)value).Value.Year == 1)
                    kryptonDateTimePicker.Checked = false;
                else if (!string.IsNullOrEmpty(bindFormat))
                    kryptonDateTimePicker.Value = (DateTime)value;
                else
                    kryptonDateTimePicker.Value = (DateTime)value;
            }
        }

        public static BindingContextCustomAttribute GetCustomAttribute(this KryptonDateTimePicker kryptonDateTimePicker)
        {
            return GetProvider().GetCustomAttribute(kryptonDateTimePicker);
        }

        private static BindingContextAttributeProvider GetProvider()
        {
            return ServiceHelper.GetService<BindingContextAttributeProvider>() ??
        throw new InvalidOperationException("BindingContextAttributeProvider is not registered in the service GetProvider().");
        }
    }
}

