using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using DBEntitys;
using GameMessage;

namespace Server.DB.Sql
{
    public class DbSearchField<T>
    {
        public Dictionary<string, object> Fields => _fields;

        private readonly Dictionary<string, object> _fields;
        private readonly List<PropertyInfo> _properties;

        public DbSearchField(Dictionary<string, object> fields)
        {
            _fields = new Dictionary<string, object>(fields);
            _properties = new List<PropertyInfo>(typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance));
        }

        public void Remove(string key)
        {
            _fields.Remove(key);
        }

        public bool Contains(string key)
        {
            return _fields.ContainsKey(key);
        }

        public int GetInt(string key)
        {
            if (!Contains(key)) return 0;
            int.TryParse(_fields[key].ToString(), out int value);
            return value;
        }

        public bool GetBool(string key)
        {
            if (!Contains(key)) return false;
            bool.TryParse(_fields[key].ToString(), out bool value);
            return value;
        }

        public string GetString(string key)
        {
            if (!Contains(key)) return string.Empty;
            var value = _fields[key].ToString();
            return value;
        }

        /// <summary>
        /// 根据属性注解自动构建SQL条件到SqlBuilder
        /// </summary>
        public void BuildWhereConditions(SqlBuilder sb)
        {
            foreach (var prop in _properties)
            {
                // 检查是否忽略
                if (prop.GetCustomAttribute<QueryIgnoreAttribute>() != null)
                    continue;

                var propName = prop.Name;
                string searchName = propName;

                // 检查 FieldNameAttribute 别称
                var fieldNameAttr = prop.GetCustomAttribute<DBFieldNameAttribute>();
                if (fieldNameAttr != null && !string.IsNullOrEmpty(fieldNameAttr.FieldName))
                {
                    searchName = fieldNameAttr.FieldName;
                }

                if (!Contains(searchName))
                    continue;

                var value = _fields[searchName];
                if (value == null)
                    continue;

                // 检查注解类型并应用对应的查询方式
                var dateRangeAttr = prop.GetCustomAttribute<DateRangeFieldAttribute>();
                if (dateRangeAttr != null)
                {
                    var dateRange = dateRangeAttr.IsDateRange ? GetDateRange(searchName) : GetDefaultDate(searchName);
                    sb.WhereBetween(propName, dateRange.Start, dateRange.End);
                }
                else if (prop.GetCustomAttribute<LikeFieldAttribute>() != null)
                {
                    sb.WhereLike(propName, value.ToString());
                }
                else if (prop.GetCustomAttribute<InFieldAttribute>() != null)
                {
                    var attr = prop.GetCustomAttribute<InFieldAttribute>();
                    var values = value.ToString().Split(attr.Separator).ToList();
                    sb.WhereIn(propName, values);
                }
                else
                {
                    // 默认使用等于查询
                    sb.WhereEqual(propName, value);
                }

                Remove(searchName);
            }
        }

        /// <summary>
        /// 获取实体字段（不包含特殊处理的字段，如分页参数）
        /// </summary>
        public Dictionary<string, object> GetEntityFields()
        {
            Dictionary<string, object> fields = new Dictionary<string, object>();
            foreach (var prop in _properties)
            {
                var propName = prop.Name;
                // 检查 FieldNameAttribute 别称
                var fieldNameAttr = prop.GetCustomAttribute<DBFieldNameAttribute>();
                if (fieldNameAttr != null && !string.IsNullOrEmpty(fieldNameAttr.FieldName))
                {
                    if (Contains(fieldNameAttr.FieldName))
                    {
                        fields[propName] = _fields[fieldNameAttr.FieldName];
                        continue;
                    }
                }

                if (Contains(propName))
                {
                    fields[propName] = _fields[propName];
                }
            }
            return fields;
        }

        #region 前端约定好的通用参数字段
        
        public (DateTime Start, DateTime End) GetDefaultDate(string key)
        {
            if (!Contains(key))
                return (DateTime.Now, DateTime.Now);
            var value = GetString(key);
            var startDate = DateTime.Parse(value);
            var endDate = DateTime.Parse(value);
            if (endDate == startDate)
            {
                endDate = endDate.AddDays(1).AddSeconds(-1);
            }
            
            return (startDate, endDate);
        }
        
        public (DateTime Start, DateTime End) GetDateRange(string key)
        {
            if (!Contains(key))
                return (DateTime.Now, DateTime.Now);
            
            var ranges = GetString(key).Split(',');
            var startDate = DateTime.Parse(ranges[0]);
            var endDate = DateTime.Parse(ranges[1]);
            if (endDate == startDate)
            {
                endDate = endDate.AddDays(1).AddSeconds(-1);
            }
            
            return (startDate, endDate);
        }
        
        public DataPage GetPage()
        {
            return new DataPage()
            {
                PageId = GetPageIndex(),
                PageSize = GetPageSize()
            };
        }

        public int GetPageIndex()
        {
            if (!Contains("pageIndex"))
                return 1;

            return GetInt("pageIndex");
        }

        public int GetPageSize()
        {
            if (!Contains("pageSize"))
                return 10;
            return GetInt("pageSize");
        }

        #endregion
    }
}