using Microsoft.Extensions.Caching.Distributed;
using System;
using XYY.Core.Standard.Data.Infrastructure;
using Dapper;
using XYY.Core.Standard;
using System.Threading.Tasks;

namespace XYY.DataMSHelper.Standard
{

    public interface ICreateHelper
    {

    }

    public class CreaterHelper : ICreateHelper
    {
        public IUnitOfWork _unitOfWork;
        public CreaterHelper(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        private string baseText = null;

        public string GetBaseText(bool isLog)
        {
            if (string.IsNullOrEmpty(baseText))
            {
                string fileName = isLog ? "LogBase.txt" : "EntityBase.txt";
                string filePath = System.IO.Path.Combine(AppContext.BaseDirectory, "Sql", fileName);
                baseText = System.IO.File.ReadAllText(filePath);
            }
            return baseText;
        }

        public async Task CreateTables(string Namespace, string dll)
        {
            var assemeble = System.Reflection.Assembly.Load(dll);
            var types = assemeble.GetTypes();
            foreach (var t in types)
            {
                if (t.IsClass)
                {
                    if (t.Namespace == Namespace)
                    {
                        if (t.BaseType == typeof(BaseEntity))
                        {
                            await CreateTable(t, false);
                        }
                        else if (t.BaseType == typeof(BaseLogEntity))
                        {
                            await CreateTable(t, true);
                        }
                    }
                }
            }
        }

        public async Task CreateTable(Type type, bool isLog)
        {
            if (type.Name.Contains("View"))
            {
                return;
            }

            var pros = type.GetProperties();
            System.Text.StringBuilder columns = new System.Text.StringBuilder();
            foreach (var pro in pros)
            {
                string columnType = "";
                if (string.Equals(pro.Name, "CreateUserName", StringComparison.OrdinalIgnoreCase)
                    ||
                    (string.Equals(pro.Name, "UpdateUserName", StringComparison.OrdinalIgnoreCase)
                    ))
                {
                    columnType = "nvarchar(16)";
                }
                else if (pro.Name.Equals("Id", StringComparison.OrdinalIgnoreCase))
                {
                    if (isLog)
                    {
                        columnType = "[int] IDENTITY(1,1) NOT NULL";
                    }
                    else
                    {
                        columnType = "[int] NOT NULL";
                    }
                }
                else if (pro.PropertyType.IsEnum)
                {
                    columnType = "int";
                }
                else
                {
                    var pt = pro.PropertyType;
                    if (pt == typeof(int))
                    {
                        columnType = "int Not Null";
                    }
                    else if (pt == typeof(string))
                    {
                        columnType = "nvarchar(64) Null";
                    }
                    else if (pt == typeof(System.DateTime?))
                    {
                        columnType = "dateTime Null";
                    }
                    else if (pt == typeof(System.DateTime))
                    {
                        columnType = "dateTime Not Null";
                    }
                    else if (pt == typeof(decimal))
                    {
                        columnType = "decimal(18,2) Not Null";
                    }
                }
                if (!string.IsNullOrEmpty(columnType))
                {
                    columns.AppendLine($"[{pro.Name}] {columnType},");
                }
            }
            string baseText = GetBaseText(isLog);
            string sql = string.Format(baseText, type.Name, columns.ToString());
            Console.WriteLine(sql);
            await _unitOfWork.ExecuteAsync(sql);
        }

    }
}
