
using Fluid;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Test.GenerateFolder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using static System.Net.Mime.MediaTypeNames;

partial class Program
{

    static void Main(string[] args)
    {
        //发布的目录和项目的目录有区别的  
        var rootPath = AppContext.BaseDirectory.Replace(@"\bin\net8.0\", "").Replace(@"\bin\Release\net8.0\", "");

        var templateFolderPath = Path.Combine(rootPath, "LiquidTemplate");
        var outPutTemplateFolderPath = Path.Combine(rootPath, "LiquidTemplateOutPut");

        #region 生成文件目录准备
        if (!Directory.Exists(outPutTemplateFolderPath))
        {
            Directory.CreateDirectory(outPutTemplateFolderPath);
        }

        #region 废弃 没必要分目录，还是手动设置文件夹
        //var servicePath = Path.Combine(outPutTemplateFolderPath, "Service");
        //var iServicePath = Path.Combine(outPutTemplateFolderPath, "IService");
        //var entityPath = Path.Combine(outPutTemplateFolderPath, "Entity");
        //var dtoPath = Path.Combine(outPutTemplateFolderPath, "DTO");

        //if (!Directory.Exists(servicePath))
        //{
        //    Directory.CreateDirectory(servicePath);
        //}
        //if (!Directory.Exists(iServicePath))
        //{
        //    Directory.CreateDirectory(iServicePath);
        //}
        //if (!Directory.Exists(entityPath))
        //{
        //    Directory.CreateDirectory(entityPath);
        //}
        //if (!Directory.Exists(dtoPath))
        //{
        //    Directory.CreateDirectory(dtoPath);
        //}
        #endregion

        #endregion


        // 要生成的表名数组
        var tableNames = new List<string>(args);

        var argsStr = string.Join("", args) ??string.Empty;

        if ( argsStr.Contains("-")|| argsStr.Contains("application") || argsStr.Contains("Test") || argsStr.Contains("."))
        {
            tableNames = new List<string>();
        }


        try
        {
            //便利所有模板文件进行生成操作
            foreach (var templateFilePath in Directory.GetFiles(templateFolderPath))
            {

                var fileName = Path.GetFileNameWithoutExtension(templateFilePath);

                //模板放入具体的文件夹
                //var folder = fileName == "Entity" ? "Entity" : fileName.Replace("Entity", "");

                foreach (var tableName in tableNames)
                {
                    var model = new TemplateModel
                    {
                        TableName = tableName,

                        IsPaged = true,

                        TableFieLdList = GetTableFiledList(tableName)
                    };

                    var options = new TemplateOptions();
                    options.MemberAccessStrategy.Register<TableProperty>();

                    var parser = new FluidParser();

                    var source = File.ReadAllText(templateFilePath);

                    if (parser.TryParse(source, out var template, out var error))
                    {
                        var context = new TemplateContext(model, options, true);

                        //Console.WriteLine(template.Render(context));

                        string outputFilePath = Path.Combine(outPutTemplateFolderPath, /*folder,*/ $"{fileName.Replace("Entity", tableName)}.cs");


                        File.WriteAllText(outputFilePath, template.Render(context));
                    }
                    else
                    {
                        Console.WriteLine($"Error: {error}");
                    }



                }
            }
        }
        catch (Exception ex)
        {

            Console.WriteLine($"Error: {ex.Message}");
        }


    }

    // Model class to pass data to the template
    public class TemplateModel
    {
        public string TableName { get; set; }

        //生成的列表是是分页 还是不分页
        public bool IsPaged { get; set; }

        public DateTime DateTimeNow = DateTime.Now;


        public List<TableProperty> TableFieLdList { get; set; }




        public List<TableProperty> AddOrUpdateFieldList => TableFieLdList.Where(t => !AddOrUpdateExcludeNameList.Contains(t.FieldName)).ToList();
        public List<TableProperty> ViewListFieldList => TableFieLdList.Where(t => ListInCludeNameList.Contains(t.FieldName)).ToList();
        public List<TableProperty> QueryListFieldList => TableFieLdList.Where(t => !AddOrUpdateExcludeNameList.Contains(t.FieldName) && t.IsPrimarykey==false).ToList();

        //添加和更新模型排除的字段名
        public List<string> AddOrUpdateExcludeNameList = new List<string>() { "CreateUserId", "UpdateUserId", "CreateTime", "UpdateTime", "DeleteUserId", "IsDeleted", "DeletedTime" };

        public List<string> ListInCludeNameList = new List<string>() { "CreateTime", "UpdateTime" };

        // 列表视图模型名称
        public string TableNameView => TableName + "View";
        //列表查询模型名称
        public string TableNameQuery => TableName + "Query";
        //添加和编辑模型名称
        public string TableNameAddOrEdit => TableName + "AddOrEdit";
        //删除主键属性名
        public string LowercaseTableNameId => char.ToLower(TableName[0]) + TableName.Substring(1) + "Id";

        public string LowercaseRepositoryName => $"_{char.ToLower(TableName[0]) + TableName.Substring(1)}Repository";

        public string LowercaseQueryableName => $"{char.ToLower(TableName[0]) + TableName.Substring(1)}Queryable";

    }

    public class TableProperty
    {
        public string ColumnName { get; set; }
        public string FieldName { get; set; }

        public string CSharpType { get; set; }

        public bool IsNullable { get; set; }

        // 自动赋值  String.Empty  避免 数据库存储Null
        public bool IsCSharpString => CSharpType.ToLower() == "string";

        public int? MaxLength { get; set; }

        public bool IsPrimarykey { get; set; }

    }


    private static List<TableProperty> GetTableFiledList(string tableName)
    {

        #region 直接通过上下文拿到实体信息


        var contextOptions = new DbContextOptionsBuilder<IRaCISDBContext>().UseSqlServer(@"Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true").Options;

        using var dbContext = new IRaCISDBContext(contextOptions);

        var dbModel = dbContext.Model;

        var entityType = dbModel.GetEntityTypes().Where(t => t.GetTableName() == tableName).FirstOrDefault();

        if (entityType != null)
        {
            var list = entityType.GetProperties().Select(property => new TableProperty()
            {
                FieldName = property.Name,
                ColumnName = property.GetColumnName(),
                IsNullable = property.IsNullable,
                IsPrimarykey = property.IsKey(),
                CSharpType = GetCSharpType(property.ClrType),
            }).ToList();

            return list;
        }

        return new List<TableProperty>();

        #endregion
    }

    static string GetCSharpType(Type type)
    {
        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            var underlyingType = Nullable.GetUnderlyingType(type);
            return $"{GetCSharpType(underlyingType)}?";
        }

        return type switch
        {
            _ when type == typeof(int) => "int",
            _ when type == typeof(long) => "long",
            _ when type == typeof(short) => "short",
            _ when type == typeof(byte) => "byte",
            _ when type == typeof(bool) => "bool",
            _ when type == typeof(decimal) => "decimal",
            _ when type == typeof(double) => "double",
            _ when type == typeof(float) => "float",
            _ when type == typeof(Guid) => "Guid",
            _ when type == typeof(DateTime) => "DateTime",
            _ when type == typeof(string) => "string",
            _ => type.Name // 非常见类型，返回 .NET 类型名称
        };
    }

    #region 核对code first 暂时屏蔽

    public void CheckCodeFirst()
    {
        //var contextOptions = new DbContextOptionsBuilder<TempContext>()
        //    .UseSqlServer(@"Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true").Options;

        //using var dbContext = new TempContext(contextOptions);
        using var dbContext = new TempContext();

        var dbModel = dbContext.Model;

        foreach (var entityType in dbModel.GetEntityTypes())
        {
            string tableName = entityType.GetTableName();
            Console.WriteLine($"Table: {tableName}");

            foreach (var property in entityType.GetProperties())
            {
                string columnName = property.GetColumnName();
                string dataType = property.ClrType.Name;
                bool isNullable = property.IsNullable;
                int? maxLength = property.GetMaxLength();  // 获取最大长度
                string columnType = property.GetColumnType();  // 获取数据库中的列类型
                bool isKey = property.IsKey();  // 判断是否为主键
                bool isIndex = property.IsIndex();  // 判断是否是索引
                object defaultValue = property.GetDefaultValue();  // 获取默认值
                bool isGenerated = property.ValueGenerated != Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.Never;  // 判断是否是自动生成的值

                Console.WriteLine($"    Column: {columnName}, Data Type: {dataType}, Is Nullable: {isNullable}, Max Length: {maxLength}, Column Type: {columnType}, Is Key: {isKey}, Is Index: {isIndex}, Default Value: {defaultValue}, Is Generated: {isGenerated}");
            }
        }
    }

    #endregion
}
