using DocumentFormat.OpenXml.Spreadsheet;
using Infrastructure;
using Microsoft.Extensions.Configuration;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using OpenAuth.App.Base;
using OpenAuth.App.FormModule.Request;
using OpenAuth.App.Interface;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using SqlSugar;
using System.Linq.Expressions;
using System.Text;
using Castle.Core.Internal;
using DocumentFormat.OpenXml.Drawing.Charts;
using OpenAuth.App.BaseApp.Base;

namespace OpenAuth.App.FormModule
{
    public class FormModuleApp : SqlSugarBaseApp<Repository.Domain.FormModuleEntity, SugarDbContext>
    {
        private IConfiguration _configuration;

        public FormModuleApp(ISugarUnitOfWork<SugarDbContext> unitWork,
            ISimpleClient<Repository.Domain.FormModuleEntity> repository, IAuth auth,
            IConfiguration configuration) : base(unitWork, repository, auth)
        {
            _configuration = configuration;
        }

        #region 查询数据

        /// <summary>
        /// 模块获取分页列表
        /// </summary>
        /// <param name="keyword">筛选关键词</param>
        /// <param name="pmoduleid">父级菜单</param>
        /// <param name="pageindex">当前页</param>
        /// <param name="pagesize">每页条数</param>
        /// <returns></returns>
        public async Task<Response<PageInfo<List<FormModuleEntity>>>> GetModulePageList(string keyword,
            string pmoduleid, int pageindex, int pagesize)
        {
            //定义且实例化分页数据
            RefAsync<int> totalCount = 0;
            //PageModel page = new PageModel { PageIndex = pageindex, PageSize = pagesize, TotalCount = totalCount };

            ////筛选条件处理
            //Expression<Func<FormModuleEntity, bool>> expression = PredicateBuilder.True<FormModuleEntity>(); ;
            //if (!string.IsNullOrEmpty(keyword))
            //{
            //    expression = expression.And(t => t.Code.Contains(keyword) || t.Name.Contains(keyword));
            //}
            //if (!string.IsNullOrEmpty(pmoduleid))
            //{
            //    expression = expression.And(t => t.PmoduleId == pmoduleid);
            //}

            //多租户
            //if (ConfigHelper.GetConfig().IsSass)
            //{
            //    expression = expression.And(t => t.IsMain != 1);
            //}

            //数据查询并返回
            var info = await this.Repository.AsQueryable()
                .WhereIF(!string.IsNullOrEmpty(keyword), t => t.Code.Contains(keyword) || t.Name.Contains(keyword))
                .WhereIF(!string.IsNullOrEmpty(pmoduleid), t => t.PmoduleId == pmoduleid)
                .OrderByDescending(t => t.CreateDate)
                .ToPageListAsync(pageindex, pagesize, totalCount);

            return new Response<PageInfo<List<FormModuleEntity>>>
            {
                Result = new PageInfo<List<FormModuleEntity>>
                {
                    Items = info,
                    Total = totalCount
                }
            };
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<Response<List<FormModuleEntity>>> GetList()
        {
            var info = await this.Repository.GetListAsync(r => r.EnabledMark == 1);
            return new Response<List<FormModuleEntity>>
            {
                Result = info
            };
        }

        /// <summary>
        /// 获取实体数据
        /// </summary>
        /// <param name="id">发布表单模板的id（formmodule的id）</param>
        /// <returns></returns>
        public async Task<Response<FormModuleEntity>> GetForm(string id)
        {
            var info = await this.Repository.GetByIdAsync(id);
            return new Response<FormModuleEntity>
            {
                Result = info
            };
        }

        /// <summary>
        /// 根据菜单主键id获取实体数据
        /// </summary>
        /// <param name="id">菜单id（SYSModule的id）</param>
        /// <returns></returns>
        public async Task<Response<FormModuleEntity>> GetFormByModuleId(string id)
        {
            var info = await this.Repository.GetFirstAsync(r => r.ModuleId == id);
            return new Response<FormModuleEntity>
            {
                Result = info
            };
        }

        /// <summary>
        /// 根据编号获取实体数据
        /// </summary>
        /// <param name="code">编号</param>
        /// <returns></returns>
        public async Task<Response<FormModuleEntity>> GetFormByCode(string code)
        {
            var info = await this.Repository.GetFirstAsync(r => r.Code == code);
            return new Response<FormModuleEntity>
            {
                Result = info
            };
        }

        /// <summary>
        /// 获取设计数据
        /// </summary>
        /// <param name="code">编码</param>
        /// <returns></returns>
        public async Task<Response<FormModuleSchemeReq>> GetEntityByCode(string code)
        {
            var info = new FormModuleSchemeReq();
            info.Entity = await this.Repository.GetFirstAsync(r => r.Code == code);
            if (info.Entity != null)
            {
                info.FormScheme = await base.Repository
                    .ChangeRepository<SugarRepositiry<Repository.Domain.FormScheme>>()
                    .GetFirstAsync(r => r.Id == info.Entity.FormVerison);
            }

            return new Response<FormModuleSchemeReq>
            {
                Result = info
            };
        }

        #endregion

        #region 增删改

        #region 添加

        /// <summary>
        /// 保存模块功能实体（新增、修改）（系统功能菜单，按钮，视图，表单四个表）
        /// </summary>
        /// <param name="keyValue">主键值</param>
        /// <param name="module">实体</param>
        /// <param name="moduleElement">按钮列表</param>
        /// <param name="moduleColumn">视图列集合</param>
        /// <param name="moduleForm">表单字段</param>
        public async Task<Response<bool>> SaveEntity(string keyValue, FormModuleEntity entity, SysModule module,
            List<SysModuleElement> moduleElement, List<SysModuleColumn> moduleColumn, List<SysModuleForm> moduleForm)
        {
            var mid = entity.ModuleId;
            var oldModuleEntity = await this.Repository.AsSugarClient().Queryable<SysModule>().Where(r => r.Id == mid)
                .FirstAsync();
            if (oldModuleEntity == null)
            {
                module.Id = mid;
                mid = string.Empty;
            }

            using (var uwo = base.UnitWork.CreateContext())
            {
                #region 添加系统菜单及下属菜单信息

                #region 添加

                if (string.IsNullOrEmpty(module.ParentId) || module.ParentId == "-1")
                {
                    module.ParentId = "0";
                }

                if (string.IsNullOrEmpty(mid))
                {
                    // 新增
                    if (string.IsNullOrEmpty(module.Id))
                    {
                        module.Id = Guid.NewGuid().ToString();
                    }

                    //module.F_CreateDate = DateTime.Now;
                    //module.F_CreateUserId = this.GetUserId();
                    //module.F_CreateUserName = this.GetUserName();
                    //module.F_DeleteMark = 0;
                    await uwo.SysModule.InsertAsync(module);
                }
                else
                {
                    // 编辑
                    await uwo.SysModule.UpdateAsync(u => new SysModule
                    {
                        ParentId = module.ParentId,
                        IconName = module.IconName,
                        ParentName = module.ParentName,
                        SortNo = module.SortNo,
                        Encode = module.Encode,
                        IsSys = module.IsSys,
                        Code = module.Code,
                        Status = module.Status,
                        CascadeId = module.CascadeId,
                        Url = module.Url
                    }, u => u.Id == mid);
                    await uwo.SysModuleElement.DeleteAsync(t => t.ModuleId == mid);
                    await uwo.SysModuleColumn.DeleteAsync(t => t.ModuleId == mid);
                    await uwo.SysModuleForm.DeleteAsync(t => t.ModuleId == mid);
                }

                int num = 0;
                if (moduleElement != null)
                {
                    foreach (var item in moduleElement)
                    {
                        item.Sort = num;
                        item.ModuleId = module.Id;
                        //item.F_ModuleButtonId = Guid.NewGuid().ToString();
                        if (string.IsNullOrEmpty(item.Id))
                        {
                            item.Id = Guid.NewGuid().ToString();
                        }

                        await uwo.SysModuleElement.InsertAsync(item);
                        num++;
                    }
                }

                if (moduleColumn != null)
                {
                    num = 0;
                    foreach (var item in moduleColumn)
                    {
                        item.SortCode = num;
                        item.ModuleId = module.Id;
                        //item.F_ModuleColumnId = Guid.NewGuid().ToString();
                        if (string.IsNullOrEmpty(item.ModuleColumnId))
                        {
                            item.ModuleColumnId = Guid.NewGuid().ToString();
                        }

                        await uwo.SysModuleColumn.InsertAsync(item);
                        num++;
                    }
                }

                if (moduleForm != null)
                {
                    num = 0;
                    foreach (var item in moduleForm)
                    {
                        item.SortCode = num;
                        item.ModuleId = module.Id;
                        //item.F_ModuleFormId = Guid.NewGuid().ToString();
                        if (string.IsNullOrEmpty(item.ModuleFormId))
                        {
                            item.ModuleFormId = Guid.NewGuid().ToString();
                        }

                        await uwo.SysModuleForm.InsertAsync(item);
                        num++;
                    }
                }

                #endregion

                #region 权限

                if (!string.IsNullOrEmpty(entity.ModuleId))
                {
                    var objectList = await this.Repository.AsSugarClient().Queryable<SysModuleElement>()
                        .Where(r => r.ModuleId == entity.ModuleId).ToListAsync();

                    List<string> buttonList = new List<string>();
                    List<string> columnList = new List<string>();
                    List<string> formList = new List<string>();

                    if (moduleElement != null)
                    {
                        foreach (var item in moduleElement)
                        {
                            buttonList.Add(item.Id);
                        }
                    }

                    if (moduleColumn != null)
                    {
                        foreach (var item in moduleColumn)
                        {
                            columnList.Add(item.ModuleColumnId);
                        }
                    }

                    if (moduleForm != null)
                    {
                        foreach (var item in moduleForm)
                        {
                            formList.Add(item.ModuleFormId);
                        }
                    }


                    if (buttonList.Count == 0)
                    {
                        await uwo.SysRoleElement.DeleteAsync(r => objectList.Select(r => r.Id).Contains(r.ElementId));
                    }
                    else
                    {
                        await uwo.SysRoleElement.DeleteAsync(r => !buttonList.Contains(r.ElementId));
                    }

                    if (columnList.Count == 0)
                    {
                        //await moduleService.BaseRepository().Delete<AuthorizeEntity>(t => t.F_ItemType == 3 && t.F_ParentId == moduleEntity.F_ModuleId);
                    }
                    else
                    {
                        await uwo.SysRoleElement.DeleteAsync(r => !buttonList.Contains(r.ElementId));
                    }

                    if (formList.Count == 0)
                    {
                        //await moduleService.BaseRepository().Delete<AuthorizeEntity>(t => t.F_ItemType == 4 && t.F_ParentId == moduleEntity.F_ModuleId);
                    }
                    else
                    {
                        await uwo.SysRoleElement.DeleteAsync(r => !buttonList.Contains(r.ElementId));
                    }
                }

                #endregion

                #endregion

                #region 表单发布模板信息添加

                entity.ModuleId = module.Id;
                if (string.IsNullOrEmpty(keyValue))
                {
                    var user = _auth.GetCurrentUser().User;
                    entity.Id = Guid.NewGuid().ToString();
                    entity.CreateDate = DateTime.Now;
                    entity.CreateUserId = user.Id.ToString();
                    entity.CreateUserName = user.Name;

                    await uwo.FormModuleEntity.InsertAsync(entity);
                }
                else
                {
                    //编辑
                    var user = _auth.GetCurrentUser().User;
                    entity.Id = keyValue;
                    entity.ModifyDate = DateTime.Now;
                    entity.ModifyUserId = user.Id.ToString();
                    entity.ModifyUserName = user.Name;
                    await uwo.FormModuleEntity.UpdateAsync(entity);
                }

                #endregion

                var flag = uwo.Commit();
                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "操作成功" : "操作失败"
                };
            }
        }


        /// <summary>
        /// 更新状态
        /// </summary>
        /// <param name="keyValue">主键</param>
        /// <param name="state">状态</param>
        /// <returns></returns>
        public async Task<Response<bool>> UpdateState(string keyValue, int state)
        {
            var entity = await this.Repository.GetByIdAsync(keyValue);
            if (entity != null)
            {
                using (var uwo = UnitWork.CreateContext())
                {
                    await uwo.FormModuleEntity.UpdateAsync(r => new FormModuleEntity
                    {
                        EnabledMark = state
                    }, r => r.Id == keyValue);

                    await uwo.SysModule.UpdateAsync(r => new SysModule
                    {
                        Status = state
                    }, r => r.Id == keyValue);

                    var flag = uwo.Commit();
                    return new Response<bool>
                    {
                        Result = flag,
                        Message = flag == true ? "操作成功" : "操作失败"
                    };
                }
            }
            else
            {
                return new Response<bool>
                {
                    Result = false,
                    Message = "数据丢失"
                };
            }
        }

        public async Task<Response<bool>> DeleteForm(string keyValue)
        {
            var entity = await this.Repository.GetByIdAsync(keyValue);
            if (entity != null)
            {
                using (var uwo = UnitWork.CreateContext())
                {
                    await uwo.FormModuleEntity.DeleteByIdAsync(keyValue);
                    await uwo.SysModule.DeleteByIdAsync(entity.ModuleId);
                    await uwo.SysModuleColumn.DeleteAsync(r => r.ModuleId == entity.ModuleId);
                    await uwo.SysModuleElement.DeleteAsync(r => r.ModuleId == entity.ModuleId);
                    await uwo.SysModuleForm.DeleteAsync(r => r.ModuleId == entity.ModuleId);
                    var flag = uwo.Commit();
                    return new Response<bool>
                    {
                        Result = flag,
                        Message = flag == true ? "操作成功" : "操作失败"
                    };
                }
            }
            else
            {
                return new Response<bool>
                {
                    Result = false,
                    Message = "数据不存在"
                };
            }
        }

        /// <summary>
        /// 根据菜单主键id删除表单发布模板信息
        /// </summary>
        /// <param name="keyValue">菜单id（Sysmodule的主键）</param>
        public async Task<Response<bool>> DeleteEntityByModuleId(string keyValue)
        {
            using (var uwo = UnitWork.CreateContext())
            {
                await uwo.FormModuleEntity.DeleteAsync(r => r.ModuleId == keyValue);
                await uwo.SysModule.DeleteByIdAsync(keyValue);
                await uwo.SysModuleColumn.DeleteAsync(r => r.ModuleId == keyValue);
                await uwo.SysModuleElement.DeleteAsync(r => r.ModuleId == keyValue);
                await uwo.SysModuleForm.DeleteAsync(r => r.ModuleId == keyValue);
                var flag = uwo.Commit();
                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "操作成功" : "操作失败"
                };
            }
        }

        #endregion

        #endregion


        #region 扩展方法

        /// <summary>
        /// 判断数据表字段重复
        /// </summary>
        /// <param name="keyValue">主键值</param>
        /// <param name="tableName">表名</param>
        /// <param name="keyName">主键名</param>
        /// <param name="filedsJson">数据字段</param>
        /// <returns></returns>
        public async Task<Response<bool>> ExistFiled(string keyValue, string tableName, string keyName,
            string filedsJson)
        {
            StringBuilder strSql = new StringBuilder();
            var tableNameList = tableName.Split(".");
            var dbCode = string.Empty;
            if (tableNameList.Length == 2)
            {
                dbCode = tableNameList[0];
                tableName = tableNameList[1];
            }

            strSql.Append("select * from " + tableName + " t where 1=1 ");
            if (!string.IsNullOrEmpty(keyValue))
            {
                strSql.Append(" AND \"" + keyName + "\" !=\'" + keyValue + "\'");
            }

            var args = filedsJson.ToJObject();
            foreach (var item in args.Properties())
            {
                if (!string.IsNullOrEmpty(item.Value.ToString()))
                {
                    strSql.Append(" AND \"" + item.Name + "\" = '" + item.Value + "'");
                }
            }

            var dt = await this.Repository.AsSugarClient().SqlQueryable<dynamic>(strSql.ToString()).ToListAsync();

            if (dt.Count == 0)
            {
                return new Response<bool>
                {
                    Result = true
                };
            }
            else
            {
                return new Response<bool>
                {
                    Result = false,
                    Message = "字段重复"
                };
            }
        }

        #endregion

        #region 获取数据库数据列表

        /// <summary>
        /// 数据表列表
        /// </summary>
        /// <param name="code">数据库编码</param>
        /// <param name="isCache">是否读取存储区</param>
        /// <returns></returns>
        public Response<List<DbTableInfo>> GetTableList(string code, string key, bool isCache = false)
        {
            using (var db = this.CodeClient(code, _configuration))
            {
                var list = db.DbMaintenance.GetTableInfoList(isCache);
                //var list = db.DbMaintenance.GetTableInfoList((dbtype, sql) =>
                //{
                //    if (dbtype == SqlSugar.DbType.Kdbndp)
                //    {
                //        return sql.Replace(@"where  relkind = 'r' and  c.oid > 16384 and c.relnamespace != 99 and c.relname not like '%pl_profiler_saved%' order by relname", @" INNER JOIN PG_NAMESPACE AS n ON c.relnamespace = n.oid where  relkind = 'r' and  c.oid > 16384 and c.relnamespace != 99 and c.relname not like '%pl_profiler_saved%' and n.nspname = 'public' order by relname");
                //    }
                //    return sql;
                //});
                var info = list.FindAll(t =>
                    t.DbObjectType == DbObjectType.Table && t.Name.ToLower() != "lr_db_codecolumns" &&
                    t.Name.ToLower() != "lr_db_codetable" && t.Name.ToLower() != "lr_db_history")
                    .WhereIF(!key.IsNullOrEmpty(), t => t.Name.ToLower().Contains(key.ToLower())).ToList();
                return new Response<List<DbTableInfo>>
                {
                    Result = info
                };
            }
        }

        #endregion

        #region 导出
        public  Response<MemoryStream> ListToExcel(System.Data.DataTable list, List<ModuleColumn> headers)
        {
            Response<MemoryStream> response = new Response<MemoryStream>();
            try
            {
                HSSFWorkbook workbook = new HSSFWorkbook();
                #region 内容样式

                IFont font1 = workbook.CreateFont(); //创建一个字体样式对象
                font1.FontName = "Microsoft YaHei"; //和excel里面的字体对应
                //font1.Boldweight = short.MaxValue;//字体加粗
                font1.FontHeightInPoints = 12; //字体大小
                ICellStyle style = workbook.CreateCellStyle(); //创建样式对象
                style.BorderBottom = BorderStyle.Thin;
                style.BorderLeft = BorderStyle.Thin;
                style.BorderRight = BorderStyle.Thin;
                style.BorderTop = BorderStyle.Thin;
                style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
                style.VerticalAlignment = VerticalAlignment.Center;
                style.SetFont(font1); //将字体样式赋给样式对象 
                style.WrapText = true;

                #endregion

                #region 标题样式

                IFont font = workbook.CreateFont(); //创建一个字体样式对象
                font.FontName = "Microsoft YaHei"; //和excel里面的字体对应
                font.Boldweight = (short)FontBoldWeight.Bold; //字体加粗
                font.FontHeightInPoints = 12; //字体大小
                ICellStyle style1 = workbook.CreateCellStyle(); //创建样式对象
                style1.BorderBottom = BorderStyle.Thin;
                style1.BorderLeft = BorderStyle.Thin;
                style1.BorderRight = BorderStyle.Thin;
                style1.BorderTop = BorderStyle.Thin;
                style1.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
                style1.VerticalAlignment = VerticalAlignment.Center;
                style1.SetFont(font); //将字体样式赋给样式对象 

                #endregion

                #region 创建表头
                int m = list.Rows.Count / 60000+1;
                for (int k = 0; k < m; k++)
                {
                    ISheet sheet = workbook.CreateSheet("Sheet"+k.ToString());
                    IRow rowHeader = sheet.CreateRow(0);
                    rowHeader.Height = 20 * 30;
                    for (int i = 0; i < headers.Count; i++)
                    {
                        ModuleColumn header = headers[i];
                        rowHeader.CreateCell(i);
                        rowHeader.Cells[i].CellStyle = style1;
                        rowHeader.Cells[i].SetCellValue(header.value);
                        sheet.SetColumnWidth(i, 20 * 350);
                    }
                    #endregion

                    #region 填充数据
                    var val = (k + 1) * 60000;
                    var num = 60000;
                    if (val > list.Rows.Count)
                    {
                        num=list.Rows.Count-k*60000;
                    }
                    for (int i = 0; i < num; i++) //循环数据
                    {
                        var item = list.Rows[k*60000+i];     //获取数据
                        IRow dataRow = sheet.CreateRow(i + 1);  //创建行
                        for (int j = 0; j < headers.Count; j++) //循环表头
                        {
                            //数据处理
                            var objValue = "";
                            if (list.Columns.Contains(headers[j].key))
                            {
                                objValue = item[headers[j].key].ToString();
                            }
                            else
                            {
                                objValue = "";
                            }
                            //创建单元格
                            dataRow.CreateCell(j);
                            dataRow.Cells[j].CellStyle = style;  //添加单元格样式
                            if (objValue != null && !string.IsNullOrEmpty(objValue.ToString()))
                            {
                                dataRow.Cells[j].SetCellValue(objValue.ToString()); //填充Excel单元格
                            }
                            else
                            {
                                dataRow.Cells[j].SetCellValue(""); //填充Excel单元格
                            }
                        }
                    }
                }

                #endregion

                response.Result = new MemoryStream();
                workbook.Write(response.Result);
                workbook = null;
                response.Result.Close();
                response.Result.Dispose();
                response.Code = 200;
                response.Message = "获取成功";
            }
            catch (Exception ex)
            {
                response.Code = 500;
                response.Message = ex.Message;
            }
            return response;
        }
        #endregion
    }
    public class ModuleColumn
    {
        public string key { get; set; }
        public string value { get; set; }
    }
}