using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WebAPIBase.NetCore.BusinessCore
{
    public sealed class StandardStrategyStringBuilder
    {
        public static string BuildStrategyString(Strategy strategy)
        {
            string result = "";
            switch (strategy.Type)
            {
                case StrategyType.StringEqual:
                    result = BuildStringEqualString(strategy);
                    break;
                case StrategyType.StringEqualEx:
                    result = BuildStringEqualStringEx(strategy);
                    break;
                case StrategyType.StringRange:
                    result = BuildStringRangeString(strategy);
                    break;
                case StrategyType.StringIn:
                    result = BuildStringInString(strategy);
                    break;
                case StrategyType.StringLike:
                    result = BuildStringLikeString(strategy);
                    break;
                case StrategyType.StringLikeEx0:
                    result = BuildStringLikeEx0String(strategy);
                    break;
                case StrategyType.StringLikeEx1:
                    result = BuildStringLikeEx1String(strategy);
                    break;
                case StrategyType.NumberIn:
                    result = BuildNumberInString(strategy);
                    break;
                case StrategyType.DateTimeEqual:
                    result = BuildDateTimeEqualString(strategy);
                    break;
                case StrategyType.DateTimeEqualOnlyDate:
                    result = BuildDateTimeEqualOnlyDateString(strategy);
                    break;
                case StrategyType.DateTimeRange:
                    result = BuildDateTimeRangeString(strategy);
                    break;
                case StrategyType.DateTimeRangeOnlyDate:
                    result = BuildDateTimeRangeOnlyDateString(strategy);
                    break;
                case StrategyType.DateTimeEqualMonth:
                    result = BuildDateTimeEqualMonthString(strategy);
                    break;
                case StrategyType.DateTimeEqualYear:
                    result = BuildDateTimeEqualYearString(strategy);
                    break;
                case StrategyType.IntegerEqual:
                    result = BuildIntegerEqualString(strategy);
                    break;
                case StrategyType.IntegerRange:
                    result = BuildIntegerRangeString(strategy);
                    break;
                case StrategyType.FloatRange:
                    result = BuildFloatRangeString(strategy);
                    break;
            }
            return result;
        }

        public static string BuildStringEqualString(Strategy strategy)
        {
            return " " + strategy.RelationFieldName + " =  '" + strategy.GetParameter(0) + "' ";
        }

        public static string BuildStringEqualStringEx(Strategy strategy)
        {
            string parameter = strategy.GetParameter(0);
            string relationFieldName = strategy.RelationFieldName;
            string text = "";
            if (parameter == BlankType._Blank.ToString("F"))
            {
                return $" len( isnull({relationFieldName},'')) = 0  ";
            }
            if (parameter == BlankType._Not_Blank.ToString("F"))
            {
                return $" len( isnull({relationFieldName},'')) > 0  ";
            }
            return string.Format(" {1}  =  '{0}' ", parameter, relationFieldName);
        }

        public static string BuildStringRangeString(Strategy strategy)
        {
            return " " + strategy.RelationFieldName + " in  (" + strategy.GetParameter(0) + ") ";
        }

        public static string BuildStringInString(Strategy strategy)
        {
            string parameter = strategy.GetParameter(0);
            if (parameter.Length == 0)
            {
                return " 1=1 ";
            }
            string[] array = parameter.Split(',', '，');
            int num = array.Length;
            string text = "";
            string relationFieldName = strategy.RelationFieldName;
            for (int i = 0; i < num; i++)
            {
                string arg = array[i];
                if (text != "")
                {
                    text += ", ";
                }
                text += string.Format("'{1}'", relationFieldName, arg);
            }
            return " " + strategy.RelationFieldName + " in  (" + text + ") ";
        }

        public static string BuildStringLikeString(Strategy strategy)
        {
            return " " + strategy.RelationFieldName + " like ('" + strategy.GetParameter(0) + "') ";
        }

        public static string BuildStringLikeEx0String(Strategy strategy)
        {
            if (strategy.GetParameterCount() == 0)
            {
                return " 1=1 ";
            }
            string text = "";
            string relationFieldName = strategy.RelationFieldName;
            IEnumerator parameterEnumerator = strategy.GetParameterEnumerator();
            while (parameterEnumerator.MoveNext())
            {
                string arg = (string)parameterEnumerator.Current;
                if (text != "")
                {
                    text += " or ";
                }
                text += $" {relationFieldName} like ('{arg}' ) ";
            }
            return "( " + text + " )";
        }

        private static string AddLikeChar(string val, string type)
        {
            string text = val;
            switch (type.ToUpper())
            {
                case "L":
                    text += "%";
                    break;
                case "R":
                    text = "%" + text;
                    break;
                case "F":
                    text = "%" + text + "%";
                    break;
            }
            return text;
        }

        public static string BuildStringLikeEx1String(Strategy strategy)
        {
            string parameter = strategy.GetParameter(0);
            if (parameter.Length == 0)
            {
                return " 1=1 ";
            }
            string[] array = parameter.Split(',', '，');
            int num = array.Length;
            string text = "";
            string relationFieldName = strategy.RelationFieldName;
            string type = "";
            if (strategy.GetParameterCount() > 1)
            {
                type = strategy.GetParameter(1);
            }
            for (int i = 0; i < num; i++)
            {
                string val = array[i];
                if (text != "")
                {
                    text += " or ";
                }
                val = AddLikeChar(val, type);
                text += $" {relationFieldName} like ('{val}' ) ";
            }
            return "( " + text + " )";
        }

        public static string BuildNumberInString(Strategy strategy)
        {
            string parameter = strategy.GetParameter(0);
            return $" {strategy.RelationFieldName} in ( {parameter} ) ";
        }

        public static string BuildIntegerEqualString(Strategy strategy)
        {
            return " " + strategy.RelationFieldName + " = " + strategy.GetParameter(0) + " ";
        }

        public static string BuildIntegerRangeString(Strategy strategy)
        {
            string parameter = strategy.GetParameter(0);
            string parameter2 = strategy.GetParameter(1);
            string text = "";
            if (parameter == "" && parameter2 == "")
            {
                return " 1=1 ";
            }
            if (parameter == "")
            {
                return " " + strategy.RelationFieldName + " <= " + parameter2 + " ";
            }
            if (parameter2 == "")
            {
                return " " + strategy.RelationFieldName + " >= " + parameter + " ";
            }
            return " " + strategy.RelationFieldName + " BETWEEN " + parameter + " and  " + parameter2 + " ";
        }

        public static string BuildFloatRangeString(Strategy strategy)
        {
            string parameter = strategy.GetParameter(0);
            string parameter2 = strategy.GetParameter(1);
            string text = "";
            if (parameter == "" && parameter2 == "")
            {
                return " 1=1 ";
            }
            if (parameter == "")
            {
                return " " + strategy.RelationFieldName + " <= " + parameter2 + " ";
            }
            if (parameter2 == "")
            {
                return " " + strategy.RelationFieldName + " >= " + parameter + " ";
            }
            return " " + strategy.RelationFieldName + " BETWEEN " + parameter + " and  " + parameter2 + " ";
        }

        public static string BuildDateTimeEqualString(Strategy strategy)
        {
            return " " + strategy.RelationFieldName + " = '" + strategy.GetParameter(0) + "' ";
        }

        public static string BuildDateTimeEqualMonthString(Strategy strategy)
        {
            return string.Format(" Year({0})={1}  and  Month({0})={2} ", strategy.RelationFieldName, strategy.GetParameter(0), strategy.GetParameter(1));
        }

        public static string BuildDateTimeEqualYearString(Strategy strategy)
        {
            return " Year(" + strategy.RelationFieldName + ") = " + strategy.GetParameter(0) + " ";
        }

        public static string BuildDateTimeEqualOnlyDateString(Strategy strategy)
        {
            return " convert(datetime,convert(varchar(10)," + strategy.RelationFieldName + ",121)) = '" + strategy.GetParameter(0) + "' ";
        }

        public static string BuildDateTimeRangeString(Strategy strategy)
        {
            string text = strategy.GetParameter(0).Trim();
            string text2 = strategy.GetParameter(1).Trim();
            string result = "";
            if (text == "" && text2 == "")
            {
                result = " 1=1 ";
            }
            else if (text != "" && text2 != "")
            {
                result = " " + strategy.RelationFieldName + " BETWEEN '" + text + "' and  '" + text2 + "' ";
            }
            else if (text != "")
            {
                result = " " + strategy.RelationFieldName + " >= '" + text + "' ";
            }
            else if (text2 != "")
            {
                result = " " + strategy.RelationFieldName + " <= '" + text2 + "' ";
            }
            return result;
        }

        public static string BuildDateTimeRangeOnlyDateString(Strategy strategy)
        {
            string text = strategy.GetParameter(0).Trim();
            string text2 = strategy.GetParameter(1).Trim();
            string result = "";
            if (text == "" && text2 == "")
            {
                result = " 1=1 ";
            }
            else if (text != "" && text2 != "")
            {
                result = " convert(datetime,convert(varchar(10)," + strategy.RelationFieldName + ",121)) BETWEEN '" + text + "' and  '" + text2 + "' ";
            }
            else if (text != "")
            {
                result = " convert(datetime,convert(varchar(10)," + strategy.RelationFieldName + ",121)) >= '" + text + "' ";
            }
            else if (text2 != "")
            {
                result = " convert(datetime,convert(varchar(10)," + strategy.RelationFieldName + ",121)) <= '" + text2 + "' ";
            }
            return result;
        }
    }
}
