// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core.Service;
using DbType = SqlSugar.DbType;
namespace Admin.NET.Core;
/// 
/// 代码生成帮助类
/// 
public static class CodeGenUtil
{
    /// 
    /// 转换大驼峰法命名
    /// 
    /// 字段名
    /// EntityBase 实体属性名称
    /// 
    public static string CamelColumnName(string columnName, string[] dbColumnNames)
    {
        if (columnName.Contains('_'))
        {
            var arrColName = columnName.Split('_');
            var sb = new StringBuilder();
            foreach (var col in arrColName)
            {
                if (col.Length > 0)
                    sb.Append(col[..1].ToUpper() + col[1..].ToLower());
            }
            columnName = sb.ToString();
        }
        else
        {
            var propertyName = dbColumnNames.FirstOrDefault(c => c.ToLower() == columnName.ToLower());
            if (!string.IsNullOrEmpty(propertyName))
            {
                columnName = propertyName;
            }
            else
            {
                columnName = columnName[..1].ToUpper() + columnName[1..].ToLower();
            }
        }
        return columnName;
    }
    public static string ConvertDataType(string dataType)
    {
        if (string.IsNullOrEmpty(dataType)) return "";
        if (dataType.StartsWith("System.Nullable"))
            dataType = new Regex(@"(?i)(?<=\[)(.*)(?=\])").Match(dataType).Value; // 中括号[]里面值
        switch (dataType)
        {
            case "System.Guid": return "Guid";
            case "System.String": return "string";
            case "System.Int32": return "int";
            case "System.Int64": return "long";
            case "System.Single": return "float";
            case "System.Double": return "double";
            case "System.Decimal": return "decimal";
            case "System.Boolean": return "bool";
            case "System.DateTime": return "DateTime";
            case "System.DateTimeOffset": return "DateTimeOffset";
            case "System.Byte": return "byte";
            case "System.Byte[]": return "byte[]";
            default:
                break;
        }
        return dataType;
    }
    // 根据数据库类型来处理对应的数据字段类型
    public static string ConvertDataType(DbColumnInfo dbColumnInfo, DbType dbType = DbType.Custom)
    {
        if (dbType == DbType.Custom)
            dbType = App.GetOptions().ConnectionConfigs[0].DbType;
        var dataType = dbType switch
        {
            DbType.Oracle => ConvertDataType_OracleSQL(string.IsNullOrEmpty(dbColumnInfo.OracleDataType) ? dbColumnInfo.DataType : dbColumnInfo.OracleDataType, dbColumnInfo.Length, dbColumnInfo.Scale),
            DbType.PostgreSQL => ConvertDataType_PostgreSQL(dbColumnInfo.DataType),
            _ => ConvertDataType_Default(dbColumnInfo.DataType),
        };
        return dataType + (dbColumnInfo.IsNullable ? "?" : "");
    }
    public static string ConvertDataType_OracleSQL(string dataType, int? length, int? scale)
    {
        switch (dataType.ToLower())
        {
            case "interval year to month":
                return "int";
            case "interval day to second":
                return "TimeSpan";
            case "smallint":
                return "Int16";
            case "int":
            case "integer":
                return "int";
            case "long":
                return "long";
            case "float":
                return "float";
            case "decimal":
                return "decimal";
            case "number":
                if (length != null)
                {
                    if (scale != null && scale > 0)
                    {
                        return "decimal";
                    }
                    else if ((scale != null && scale == 0) || scale == null)
                    {
                        if (length > 1 && length < 12)
                        {
                            return "int";
                        }
                        else if (length > 11)
                        {
                            return "long";
                        }
                    }
                    if (length == 1)
                    {
                        return "bool";
                    }
                }
                return "decimal";
            case "char":
            case "clob":
            case "nclob":
            case "nchar":
            case "nvarchar":
            case "varchar":
            case "nvarchar2":
            case "varchar2":
            case "rowid":
                return "string";
            case "timestamp":
            case "timestamp with time zone":
            case "timestamptz":
            case "timestamp without time zone":
            case "date":
            case "time":
            case "time with time zone":
            case "timetz":
            case "time without time zone":
                return "DateTime";
            case "bfile":
            case "blob":
            case "raw":
                return "byte[]";
            default:
                return "object";
        }
    }
    //PostgreSQL数据类型对应的字段类型
    public static string ConvertDataType_PostgreSQL(string dataType)
    {
        switch (dataType)
        {
            case "int2":
            case "smallint":
                return "Int16";
            case "int4":
            case "integer":
                return "int";
            case "int8":
            case "bigint":
                return "long";
            case "float4":
            case "real":
                return "float";
            case "float8":
            case "double precision":
                return "double";
            case "numeric":
            case "decimal":
            case "path":
            case "point":
            case "polygon":
            case "interval":
            case "lseg":
            case "macaddr":
            case "money":
                return "decimal";
            case "boolean":
            case "bool":
            case "box":
            case "bytea":
                return "bool";
            case "varchar":
            case "character varying":
            case "geometry":
            case "name":
            case "text":
            case "char":
            case "character":
            case "cidr":
            case "circle":
            case "tsquery":
            case "tsvector":
            case "txid_snapshot":
            case "xml":
            case "json":
                return "string";
            case "uuid":
                return "Guid";
            case "timestamp":
            case "timestamp with time zone":
            case "timestamptz":
            case "timestamp without time zone":
            case "date":
            case "time":
            case "time with time zone":
            case "timetz":
            case "time without time zone":
                return "DateTime";
            case "bit":
            case "bit varying":
                return "byte[]";
            case "varbit":
                return "byte";
            default:
                return "object";
        }
    }
    public static string ConvertDataType_Default(string dataType)
    {
        return dataType.ToLower() switch
        {
            "tinytext" or "mediumtext" or "longtext" or "mid" or "text" or "varchar" or "char" or "nvarchar" or "nchar" or "timestamp" => "string",
            "int" => "int",
            "smallint" => "Int16",
            //"tinyint" => "byte",
            "tinyint" => "bool",    // MYSQL
            "bigint" or "integer" => "long",
            "bit" => "bool",
            "money" or "smallmoney" or "numeric" or "decimal" => "decimal",
            "real" => "Single",
            "datetime" or "smalldatetime" => "DateTime",
            "float" or "double" => "double",
            "image" or "binary" or "varbinary" => "byte[]",
            "uniqueidentifier" => "Guid",
            _ => "object",
        };
    }
    /// 
    /// 数据类型转显示类型
    /// 
    /// 
    /// 
    public static string DataTypeToEff(string dataType)
    {
        if (string.IsNullOrEmpty(dataType)) return "";
        return dataType?.TrimEnd('?') switch
        {
            "string" => "Input",
            "int" => "InputNumber",
            "long" => "Input",
            "float" => "Input",
            "double" => "Input",
            "decimal" => "Input",
            "bool" => "Switch",
            "Guid" => "Input",
            "DateTime" => "DatePicker",
            _ => "Input",
        };
    }
    // 是否通用字段
    public static bool IsCommonColumn(string columnName)
    {
        var columnList = new List()
        {
            nameof(EntityBaseData.CreateOrgId),
            nameof(EntityTenant.TenantId),
            //修改,显示出 日期 【Editby shaocx,2024-05-07】
            //nameof(EntityBase.CreateTime),
            //nameof(EntityBase.UpdateTime),
            nameof(EntityBase.CreateUserId),
            nameof(EntityBase.UpdateUserId),
            //nameof(EntityBase.CreateUserName),
            //nameof(EntityBase.UpdateUserName),
            nameof(EntityBase.IsDelete)
        };
        return columnList.Contains(columnName);
    }
    // 是否不增改查询字段
    public static bool IsNoNeedCurdColumn(string columnName)
    {
        var columnList = new List()
        {
            nameof(EntityBase.CreateTime),
            nameof(EntityBase.UpdateTime),
            nameof(EntityBase.CreateUserName),
            nameof(EntityBase.UpdateUserName)
        };
        return columnList.Contains(columnName);
    }
    // 是否是 基础时间字段 
    public static bool IsEntityBaseTimeColumn(string columnName)
    {
        var columnList = new List()
        {
            nameof(EntityBase.CreateTime),
            nameof(EntityBase.UpdateTime)
        };
        return columnList.Contains(columnName);
    }
    ///// 
    ///// 校验 代码配置
    ///// 
    ///// 
    //public static void ValidateCodeGenConfig(List list)
    //{
    //    //如果是下拉框,那么就必须选择字典!【Editby shaocx,2024-04-16】
    //    foreach (var item in list)
    //    {
    //        if (IsSelect(item.EffectType) && string.IsNullOrEmpty(item.DictTypeCode))
    //        {
    //            throw Oops.Oh($"字段{item.ColumnName}的作用类型是'下拉框',字典必须选择!");
    //        }
    //        if (IsIngoreConfigAddEdit(item.ColumnName.ToLower()) && item.WhetherRequired == YesNoEnum.Y.ToString() && item.WhetherAddUpdate == YesNoEnum.N.ToString())
    //        {
    //            throw Oops.Oh($"字段{item.ColumnName}必填字段必须配置增改!");
    //        }
    //    }
    //}
    /// 
    /// 校验 代码配置
    /// 
    /// 
    public static void ValidateCodeGenConfig(List list)
    {
        //如果是下拉框,那么就必须选择字典!【Editby shaocx,2024-04-16】
        foreach (var item in list)
        {
            if (IsSelect(item.EffectType) && string.IsNullOrEmpty(item.DictTypeCode))
            {
                throw Oops.Oh($"字段{item.ColumnName}的作用类型是'下拉框',字典必须选择!");
            }
            if (IsIngoreConfigAddEdit(item.ColumnName.ToLower()) && item.WhetherRequired == YesNoEnum.Y.ToString() && item.WhetherAddUpdate == YesNoEnum.N.ToString())
            {
                throw Oops.Oh($"字段{item.ColumnName}必填字段必须配置增改!");
            }
            if (item.WhetherTable == YesNoEnum.N.ToString() && item.WhetherKeyQuery == YesNoEnum.Y.ToString())
            {
                throw Oops.Oh($"字段{item.ColumnName}列设置不显示但是配置了关键字查询!");
            }
        }
    }
    public static bool IsSelect(string effectType)
    {
        if (effectType.ToLower() == "select" || effectType == "EnumSelector")
        {
            return true;
        }
        return false;
    }
    public static bool IsIngoreConfigAddEdit(string columnName)
    {
        if (columnName.ToLower() != "id" && columnName.ToLower() != "isdelete")
        {
            return true;
        }
        return false;
    }
}