using NTDLS.SqliteDapperWrapper;

namespace ZelWiki.Repository
{
    internal static class RepositoryHelper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="orderBy"></param>
        /// <param name="orderByDirection"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static string TransposeOrderby(string filename, string? orderBy, string? orderByDirection)
        {
            var script = ManagedDataStorageInstance.TranslateSqlScript(filename);

            if (string.IsNullOrEmpty(orderBy))
            {
                return script;
            }

            var beginParentTag = "--CUSTOM_ORDER_BEGIN::";
            var endParentTag = "--::CUSTOM_ORDER_BEGIN";

            var beginConfigTag = "--CONFIG::";
            var endConfigTag = "--::CONFIG";

            while (true)
            {
                var beginParentIndex = script.IndexOf(beginParentTag, StringComparison.OrdinalIgnoreCase);
                var endParentIndex = script.IndexOf(endParentTag, StringComparison.OrdinalIgnoreCase);

                if (beginParentIndex > 0 && endParentIndex > beginParentIndex)
                {
                    var sectionText = script.Substring(beginParentIndex + beginParentTag.Length,
                        (endParentIndex - beginParentIndex) - endParentTag.Length).Trim();

                    var beginConfigIndex = sectionText.IndexOf(beginConfigTag, StringComparison.OrdinalIgnoreCase);
                    var endConfigIndex = sectionText.IndexOf(endConfigTag, StringComparison.OrdinalIgnoreCase);

                    if (beginConfigIndex >= 0 && endConfigIndex > beginConfigIndex)
                    {
                        var configText = sectionText.Substring(beginConfigIndex + beginConfigTag.Length,
                            (endConfigIndex - beginConfigIndex) - endConfigTag.Length).Trim();

                        var configs = configText.Split("\n").Select(o => o.Trim())
                            .Where(o => o.Contains('='))
                            .Select(o => (Name: o.Split("=")[0], Field: o.Split("=")[1]));

                        var selectedConfig = configs.SingleOrDefault(o =>
                            string.Equals(o.Name, orderBy, StringComparison.OrdinalIgnoreCase));

                        if (selectedConfig == default)
                        {
                            throw new Exception(
                                $"在 '{filename}' 中找不到排序字段 '{orderBy}'的映射");
                        }

                        script = script.Substring(0, beginParentIndex)
                                 + $"ORDER BY\r\n\t{selectedConfig.Field} "
                                 + (string.Equals(orderByDirection, "asc", StringComparison.InvariantCultureIgnoreCase)
                                     ? "asc"
                                     : "desc")
                                 + script.Substring(endParentIndex + endParentTag.Length);
                    }
                    else
                    {
                        throw new Exception($"在 '{filename}'中找不到配置");
                    }
                }
                else
                {
                    break;
                }
            }

            return script;
        }
    }
}