using APT.BaseData.Domain.ApiModel;
using APT.BaseData.Domain.ApiModel.PF;
using APT.BaseData.Domain.Entities.FM;
using APT.BaseData.Domain.IServices.OP;
using APT.MS.Domain.Entities.LR;
using APT.MS.Domain.Entities.SK;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace APT.SK.WebApi.Controllers.Api
{
    public class CrossDbContext : DbContext
    {
        public DbSet<T_SK_BASIC_LIBRARY> T_SK_BASIC_LIBRARY { get; set; }
        // 动态连接字符串（外部传入）
        private readonly string _connString;

        // 构造函数：动态接收连接字符串
        public CrossDbContext(string connString)
        {
            _connString = connString;
        }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            // 使用动态的连接字符串
            optionsBuilder.UseSqlServer(_connString);
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // 必须把你的实体配置进去，EF才认识它
            modelBuilder.Entity<T_SK_BASIC_LIBRARY>()
                   .Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_BASIC_LIBRARY_DETAIL>()
                   .Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID); 
            modelBuilder.Entity<T_SK_BASIC_LIBRARY_DETAIL_CONTENT>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_BASIC_LIBRARY_DETAIL_CONTENT_BASIC>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_BASIC_LIBRARY_DETAIL_CONTENT_HIDDEN>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_FM_USER_PRODUCTION_UNIT_SET>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_RISK_TYPE>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_SCOREL>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_SCOREE>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_SCOREC>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_LR_LAW>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_LR_LAW_TYPE>().Ignore(x => x.Nav_Org)
               .Ignore(x => x.DbConn)
               .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_CHECK_CONTENTS>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_CHECK_QUESTION>().Ignore(x => x.Nav_Org)
                   .Ignore(x => x.DbConn)
                   .Ignore(x => x.TaskID);
            modelBuilder.Entity<T_SK_CHECK_CONTENTS_BASIC>().Ignore(x => x.Nav_Org)
                  .Ignore(x => x.DbConn)
                  .Ignore(x => x.TaskID);
            //modelBuilder.Entity<OrgRuleDeptCheck>()
            //        .Ignore(x => x.departmentCheckedKeys);
        }
        /// <summary>
        /// 跨库查询：同服务器，多个库
        /// </summary>
        /// <param name="databaseNames">库名列表</param>
        /// <returns>跨库合并结果</returns>
        public List<T_SK_BASIC_LIBRARY> QueryCrossDatabases(string dbName)
        {
            List<T_SK_BASIC_LIBRARY> query = null;

            //foreach (var dbName in databaseNames)
            {
                // 核心：动态拼接 库名.dbo.表名
                string sql1 = $"SELECT * FROM {dbName}.dbo.T_SK_BASIC_LIBRARY";
                var libs = this.Set<T_SK_BASIC_LIBRARY>().FromSqlRaw(sql1).ToList();
                string sql2 = $"SELECT * FROM {dbName}.dbo.T_SK_BASIC_LIBRARY_DETAIL";
                var libDets = this.Set<T_SK_BASIC_LIBRARY_DETAIL>().FromSqlRaw(sql2).ToList();
                string sql3 = $"SELECT * FROM {dbName}.dbo.T_SK_BASIC_LIBRARY_DETAIL_CONTENT";
                var libDetConts = this.Set<T_SK_BASIC_LIBRARY_DETAIL_CONTENT>().FromSqlRaw(sql3).ToList();
                string sql4 = $"SELECT * FROM {dbName}.dbo.T_SK_BASIC_LIBRARY_DETAIL_CONTENT_BASIC";
                var libDetContLaws = this.Set<T_SK_BASIC_LIBRARY_DETAIL_CONTENT_BASIC>().FromSqlRaw(sql4).ToList();
                string sql5 = $"SELECT * FROM {dbName}.dbo.T_SK_BASIC_LIBRARY_DETAIL_CONTENT_HIDDEN";
                var libDetContHids = this.Set<T_SK_BASIC_LIBRARY_DETAIL_CONTENT_HIDDEN>().FromSqlRaw(sql5).ToList();
                var proUnits = GetJTProUnits(dbName);
                var riskTypes = GetJTRiskTypes(dbName);
                var libLs = GetJTLibLs(dbName);
                var libEs = GetJTLibEs(dbName);
                var libCs = GetJTLibCs(dbName);
                var laws = GetJTLaws(dbName);
                var cons = GetJTCons(dbName);
                var ques = GetJTQues(dbName);
                if (libs != null && libs.Any())
                {
                    foreach (var lib in libs)
                    {
                        lib.Nav_ProductionUnit = proUnits.FirstOrDefault(t => t.ID == lib.PRODUCTION_UNIT_ID);
                        lib.Nav_Type = riskTypes.FirstOrDefault(t => t.ID == lib.TYPE_ID);
                        lib.Nav_SCOREL = libLs.FirstOrDefault(t => t.ID == lib.SCOREL_ID);
                        lib.Nav_SCOREE = libEs.FirstOrDefault(t => t.ID == lib.SCOREE_ID);
                        lib.Nav_SCOREC = libCs.FirstOrDefault(t => t.ID == lib.SCOREC_ID);
                        lib.Nav_Details = libDets.Where(t => t.BASIC_LIBRARY_ID == lib.ID).ToList();
                        if (lib.Nav_Details != null && lib.Nav_Details.Any())
                        {
                            foreach (var libDet in lib.Nav_Details)
                            {
                                libDet.Nav_DetailContents = libDetConts.Where(t => t.BASIC_LIBRARY_DETAIL_ID == libDet.ID).ToList();
                                if (libDet.Nav_DetailContents != null && libDet.Nav_DetailContents.Any())
                                {
                                    foreach (var libDetCon in libDet.Nav_DetailContents)
                                    {
                                        libDetCon.Nav_Contents = cons.FirstOrDefault(t => t.ID == libDetCon.CHECK_CONTENTS_ID);
                                        libDetCon.Nav_DetailBasics = libDetContLaws.Where(t => t.BASIC_LIBRARY_DETAIL_CONTENT_ID == libDetCon.ID).ToList();
                                        if (libDetCon.Nav_DetailBasics != null && libDetCon.Nav_DetailBasics.Any())
                                        {
                                            foreach (var bas in libDetCon.Nav_DetailBasics)
                                            {
                                                bas.Nav_Law = laws.FirstOrDefault(t => t.ID == bas.LAW_ID);
                                            }
                                        }
                                        libDetCon.Nav_DetailHiddens = libDetContHids.Where(t => t.BASIC_LIBRARY_DETAIL_CONTENT_ID == libDetCon.ID).ToList();
                                        if (libDetCon.Nav_DetailHiddens != null && libDetCon.Nav_DetailHiddens.Any())
                                        {
                                            foreach (var hid in libDetCon.Nav_DetailHiddens)
                                            {
                                                hid.Nav_Question = ques.FirstOrDefault(t => t.ID == hid.CHECK_QUESTION_ID);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                query = libs;
                //query = query == null ? dbSet : query.UnionAll(dbSet);
            }
            return query;
            //return query ?? Enumerable.Empty<T_SK_BASIC_LIBRARY>().AsQueryable();
        }
        
        public List<T_FM_USER_PRODUCTION_UNIT_SET> GetJTProUnits(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_FM_USER_PRODUCTION_UNIT_SET";
            var proUnits = this.Set<T_FM_USER_PRODUCTION_UNIT_SET>().FromSqlRaw(sql).ToList();
            return proUnits;
        }
        public List<T_SK_RISK_TYPE> GetJTRiskTypes(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_SK_RISK_TYPE";
            var riskTypes = this.Set<T_SK_RISK_TYPE>().FromSqlRaw(sql).ToList();
            return riskTypes;
        }
        public List<T_SK_SCOREL> GetJTLibLs(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_SK_SCOREL";
            var libLs = this.Set<T_SK_SCOREL>().FromSqlRaw(sql).ToList();
            return libLs;
        }
        public List<T_SK_SCOREE> GetJTLibEs(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_SK_SCOREE";
            var libEs = this.Set<T_SK_SCOREE>().FromSqlRaw(sql).ToList();
            return libEs;
        }
        public List<T_SK_SCOREC> GetJTLibCs(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_SK_SCOREC";
            var libCs = this.Set<T_SK_SCOREC>().FromSqlRaw(sql).ToList();
            return libCs;
        }
        public List<T_LR_LAW> GetJTLaws(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_LR_LAW";
            var laws = this.Set<T_LR_LAW>().FromSqlRaw(sql).ToList();
            return laws;
        }
        public List<T_LR_LAW_TYPE> GetJTLawTypes(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_LR_LAW_TYPE";
            var lawTypes = this.Set<T_LR_LAW_TYPE>().FromSqlRaw(sql).ToList();
            return lawTypes;
        }
        public List<T_SK_CHECK_CONTENTS> GetJTCons(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_SK_CHECK_CONTENTS";
            var cons = this.Set<T_SK_CHECK_CONTENTS>().FromSqlRaw(sql).ToList();
            return cons;
        }
        public List<T_SK_CHECK_QUESTION> GetJTQues(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_SK_CHECK_QUESTION";
            var ques = this.Set<T_SK_CHECK_QUESTION>().FromSqlRaw(sql).ToList();
            return ques;
        }
        public List<T_SK_CHECK_CONTENTS_BASIC> GetJTBas(string dbName)
        {
            string sql = $"SELECT * FROM {dbName}.dbo.T_SK_CHECK_CONTENTS_BASIC";
            var ques = this.Set<T_SK_CHECK_CONTENTS_BASIC>().FromSqlRaw(sql).ToList();
            return ques;
        }
    }
}
