using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using Kit.Helpers;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Web;

namespace Kit.Helpers
{
    public static class UrlHelperExtensions
    {
        public static Func<string?>? FuncGetUserToken { get; set; }
        public static TModel? FillLayoutModel<TModel>(this Controller controller, TModel? model) where TModel : LayoutModel
        {
            model?.Fill(controller.HttpContext, controller.ControllerContext);
            return model;
        }

        public static string? TryAddExtraData(this string? uriString, bool updateIfExists = true)
        {
            if (uriString == null)
            {
                return null;
            }

            string? userToken = FuncGetUserToken != null ? FuncGetUserToken() : null;
            if (userToken != null)
            {
                uriString = uriString.SetQueryParam("userToken", userToken, updateIfExists);
            }

            string? eventNameIframe = HttpContextCore.Current.Request.TryGetEventNameIFrame();
            if (eventNameIframe != null)
            {
                uriString = uriString.SetQueryParam("eventNameIframe", eventNameIframe, updateIfExists);
            }

            return uriString;
        }

        public static string SetQueryParam(this string url, string paramName, string paramValue, bool updateIfExists)
        {
            // Разделяем URL на путь и query
            var parts = url.Split('?');
            var path = parts[0];
            var query = parts.Length > 1 ? parts[1] : "";

            // Парсим query-параметры
            var queryParams = HttpUtility.ParseQueryString(query);

            if (queryParams[paramName] == null || updateIfExists)
            {
                // Обновляем параметр
                queryParams[paramName] = paramValue;
            }

            // Собираем URL обратно
            var newQuery = queryParams.ToString();
            return path + (string.IsNullOrEmpty(newQuery) ? "" : "?" + newQuery);
        }

        public static string? ActionWithExtraData(this IUrlHelper urlHelper, UrlActionContext actionContext) => urlHelper.Action(actionContext).TryAddExtraData();
        public static string? ActionWithExtraData(this IUrlHelper urlHelper, string action, object values) => urlHelper.Action(action, values).TryAddExtraData();
        public static string? ActionWithExtraData(this IUrlHelper urlHelper, string action, string controller) => urlHelper.Action(action, controller).TryAddExtraData();
        public static string? ActionWithExtraData(this IUrlHelper urlHelper, string action, string controller, object values) => urlHelper.Action(action, controller, values).TryAddExtraData();
        public static string? ActionWithExtraData(this IUrlHelper urlHelper, string action, string controller, object values, string? protocol) => urlHelper.Action(action, controller, values, protocol).TryAddExtraData();
        public static string? ActionWithExtraData(this IUrlHelper urlHelper, string action, string controller, object values, string? protocol, string? host) => urlHelper.Action(action, controller, values, protocol, host).TryAddExtraData();
        public static string? ActionWithExtraData(this IUrlHelper urlHelper, string action, string controller, object values, string? protocol, string? host, string? fragment) => urlHelper.Action(action, controller, values, protocol, host, fragment).TryAddExtraData();
        public static string? ActionWithExtraData<TController>(this IUrlHelper urlHelper, Expression<Func<TController, Delegate>> actionSelector, object? values = null, string? protocol = null) where TController : Controller => urlHelper.Action(actionSelector, values, protocol).TryAddExtraData();
    }
}
