using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using EquipmentApi.IRepositories;
using MadRunFabric.Model;
using MadRunFabric.Common.Options;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using MadRunFabric.Common;
using System.Linq;
using EquipmentApi.Model.Dto;
using MadRunFabric.Common.Enums;

namespace EquipmentApi.Repositories
{
    public class Pro_Project_InfoRepository : BaseRepository<Pro_Project_Info, string>, IPro_Project_InfoRepository
    {
        protected readonly ILogger<BaseRepository<Pro_Project_Info, string>> _logger;
        protected readonly IMongoCollection<Sys_Department> _collection_sysdepartment;
        protected readonly IMongoCollection<Sys_Provinces> _collection_sys_provinces;
        protected readonly IMongoCollection<Sys_City> _collection_sys_city;
        protected readonly IMongoCollection<Sys_Building> _collection_sys_buliding;
        protected readonly IMongoCollection<Sys_Floor> _collection_sys_floor;
        protected readonly IMongoCollection<Sys_DictionaryValue> _collection_sys_dictionaryvalue;
        protected readonly IMongoCollection<Eqp_Equipment_Info> _collection_eqp_equipment_info;
        protected readonly IMongoCollection<Sys_User_Account> _collection_sys_user_account;
        protected readonly IMongoCollection<Wo_Repair_Base> _collection_wo_repair_base;
        protected readonly IMongoCollection<Sys_SystemConfig> _collection_sys_systemconfig;
        protected readonly IMongoCollection<Pro_Project_User> _collection_pro_project_user;
        public Pro_Project_InfoRepository(IOptions<MongodbOptions> settings, ILogger<BaseRepository<Pro_Project_Info, string>> logger) : base(settings, logger)
        {
            _collection_sysdepartment = _context.GetCollection<Sys_Department>();
            _collection_sys_provinces = _context.GetCollection<Sys_Provinces>();
            _collection_sys_city = _context.GetCollection<Sys_City>();
            _collection_sys_buliding = _context.GetCollection<Sys_Building>();
            _collection_sys_floor = _context.GetCollection<Sys_Floor>();
            _collection_sys_dictionaryvalue = _context.GetCollection<Sys_DictionaryValue>();
            _collection_eqp_equipment_info = _context.GetCollection<Eqp_Equipment_Info>();
            _collection_sys_user_account = _context.GetCollection<Sys_User_Account>();
            _collection_sys_systemconfig = _context.GetCollection<Sys_SystemConfig>();
            _collection_wo_repair_base= _context.GetCollection<Wo_Repair_Base>();
            _collection_pro_project_user= _context.GetCollection<Pro_Project_User>();
            _logger = logger;
        }

        /// <summary>
        /// 列表 -  Linq 关联查询 分页
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="recordCount"></param>
        /// <returns></returns>
        public IEnumerable<object> GetListsByPage(string keyword, string stime, string etime, int isdq, UserAccountInfoModel userinfo, int pageIndex, int pageSize, out int recordCount)
        {
            var listApp = new List<FilterDefinition<Pro_Project_Info>>();
            listApp.Add(Builders<Pro_Project_Info>.Filter.Eq("isdelete", 0));

            if (isdq == 1)
            {
                var dadays = (from p in _collection_sys_systemconfig.AsQueryable() where p.isdelete == false && p.paramcode == "XMDQTXDAYS" select p).FirstOrDefault();
                if (dadays != null)
                {
                    int days = Int32.Parse(dadays.paramvalue);
                    var dqdate = DateTime.Now.AddDays(days).ToString("yyyy-MM-dd");
                    listApp.Add(Builders<Pro_Project_Info>.Filter.Lte("project_endtime", dqdate));
                }
            }
            if (isdq == 2)
            {
                listApp.Add(Builders<Pro_Project_Info>.Filter.Gt("project_endtime", DateTime.Now.ToString("yyyy-MM-dd")));
            }

            //if (userinfo.isallproject == 0)
            //    listApp.Add(Builders<Pro_Project_Info>.Filter.Where(s => userinfo.projectlist.Contains(s.id)));

            var filter = Builders<Pro_Project_Info>.Filter.And(listApp);

            var lists = _collection.Find(filter).ToList();

            //关联查询 Pro_ProjectDto
            var query =
                from pro in lists
                join province in _collection_sys_provinces.AsQueryable() on pro.project_province equals province.provincecode into provinceDefa
                join city in _collection_sys_city.AsQueryable() on pro.project_city equals city.citycode into cityDefa
                join dic_pro in _collection_sys_dictionaryvalue.AsQueryable() on pro.project_property equals dic_pro.id into dic_proDefa
                join dic_nur in _collection_sys_dictionaryvalue.AsQueryable() on pro.project_nature equals dic_nur.id into dic_nurDefa
                where pro.isdelete == 0
                orderby pro.createtime descending
                select new
                {
                    pro.id,
                    pro.project_name,
                    pro.project_shortname,
                    pro.project_province,
                    provincename = provinceDefa != null && provinceDefa.Count() > 0 ? provinceDefa.First().provincename : null,
                    pro.project_city,
                    cityname = cityDefa != null && cityDefa.Count() > 0 ? cityDefa.First().cityname : null,
                    pro.project_property,
                    protypename = dic_proDefa != null && dic_proDefa.Count() > 0 ? dic_proDefa.First().name : null, //项目属性
                    pro.project_nature,
                    naturename = dic_nurDefa != null && dic_nurDefa.Count() > 0 ? dic_nurDefa.First().name : null, //项目性质
                    pro.project_resperson,
                    pro.project_starttime,
                    pro.project_endtime,
                    //pro.project_cycle,
                    pro.project_order,
                    //pro.project_equipmentvariety,
                    pro.project_plans,
                    pro.project_pic,
                    pro.project_profile,
                    //pro.project_remind,
                    pro.isend,
                    pro.endby,
                    pro.endtime,
                    pro.createtime
                };
            #region 查询条件
            if (!string.IsNullOrEmpty(keyword))
                query = query.Where(it => it.project_name.Contains(keyword) || it.project_resperson.Contains(keyword));     //项目名称，负责人
            if (!string.IsNullOrEmpty(stime))
                query = query.Where(it => it.createtime >= Convert.ToDateTime(stime + " 00:00:00"));
            if (!string.IsNullOrEmpty(etime))
                query = query.Where(it => it.createtime <= Convert.ToDateTime(etime + " 23:59:59"));

            #endregion

            recordCount = query.Count();
            var querys = query.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            //var pros = querys.Select(p => p.id);
            //var equlist = (from p in _collection_eqp_equipment_info.AsQueryable() where pros.Contains(p.projectid) && p.isdelete==0 select p).ToList();
            //var userlist = (from p in _collection_sys_user_account.AsQueryable() where p.delete_flag == false select p).ToList();

            //var list = querys.Select(pro => new
            //{
            //    pro.id,
            //    pro.project_name,
            //    pro.project_province,
            //    pro.provincename,
            //    pro.project_city,
            //    pro.cityname,
            //    pro.project_property,
            //    pro.protypename,
            //    pro.project_nature,
            //    pro.naturename,
            //    project_membernum = userlist.Where(p => p.projectlist.Contains(pro.id)).Count(),
            //    pro.project_resperson,
            //    pro.project_starttime,
            //    pro.project_endtime,
            //    //pro.project_cycle,
            //    pro.project_order,
            //    //pro.project_equipmentvariety,
            //    project_equipmentnum = equlist.Where(p => p.projectid == pro.id).Count(),
            //    pro.project_plans,
            //    pro.project_pic,
            //    pro.project_profile,
            //    //pro.project_remind,
            //    pro.isend,
            //    pro.endby,
            //    pro.endtime,
            //    pro.createtime
            //});
            return querys;
        }

        /// <summary>
        /// 列表 - Linq 关联查询
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="recordCount"></param>
        /// <returns></returns>
        public IEnumerable<object> GetAppLists(string keyword, UserAccountInfoModel userinfo)
        {
            //var equlist = (from p in _collection_eqp_equipment_info.AsQueryable() where p.isdelete == 0 select p).ToList();
            //var userlist = (from p in _collection_sys_user_account.AsQueryable() where p.delete_flag == false select p).ToList();
            //关联查询 Pro_ProjectDto
            var query =
                from pro in _collection.AsQueryable()
                join province in _collection_sys_provinces.AsQueryable() on pro.project_province equals province.provincecode into provinceDefa
                join city in _collection_sys_city.AsQueryable() on pro.project_city equals city.citycode into cityDefa
                join dic_pro in _collection_sys_dictionaryvalue.AsQueryable() on pro.project_property equals dic_pro.id into dic_proDefa
                join dic_nur in _collection_sys_dictionaryvalue.AsQueryable() on pro.project_nature equals dic_nur.id into dic_nurDefa
                where pro.isdelete == 0
                orderby pro.createtime descending
                select new
                {
                    pro.id,
                    pro.project_name,
                    pro.project_shortname,
                    pro.project_province,
                    provincename = provinceDefa != null && provinceDefa.Count() > 0 ? provinceDefa.First().provincename : null,
                    pro.project_city,
                    cityname = cityDefa != null && cityDefa.Count() > 0 ? cityDefa.First().cityname : null,
                    pro.project_property,
                    protypename = dic_proDefa != null && dic_proDefa.Count() > 0 ? dic_proDefa.First().name : null, //项目属性
                    pro.project_nature,
                    naturename = dic_nurDefa != null && dic_nurDefa.Count() > 0 ? dic_nurDefa.First().name : null, //项目性质
                    //project_membernum = userlist.Where(p => p.projectid == pro.id).Count(),
                    pro.project_resperson,
                    pro.project_starttime,
                    pro.project_endtime,
                    //pro.project_cycle,
                    pro.project_order,
                    //pro.project_equipmentvariety,
                    //project_equipmentnum = equlist.Where(p => p.projectid == pro.id).Count(),
                    pro.project_plans,
                    pro.project_pic,
                    pro.project_profile,
                    //pro.project_remind,
                    pro.isend,
                    pro.endby,
                    pro.endtime,
                    pro.createtime
                };
            #region 查询条件
            if (!string.IsNullOrEmpty(keyword))
                query = query.Where(it => it.project_name.Contains(keyword) || it.project_resperson.Contains(keyword));     //项目名称，负责人
            if (userinfo.isallproject == 0)
                query = query.Where(it => userinfo.projectlist.Contains(it.id));
            #endregion

            //var list = query.ToList().Select(pro => new
            //{
            //    pro.id,
            //    pro.project_name,
            //    pro.project_province,
            //    pro.provincename,
            //    pro.project_city,
            //    pro.cityname,
            //    pro.project_property,
            //    pro.protypename,
            //    pro.project_nature,
            //    pro.naturename,
            //    project_membernum = userlist.Where(p => p.projectlist.Contains(pro.id)).Count(),
            //    pro.project_resperson,
            //    pro.project_starttime,
            //    pro.project_endtime,
            //    //pro.project_cycle,
            //    pro.project_order,
            //    //pro.project_equipmentvariety,
            //    project_equipmentnum = equlist.Where(p => p.projectid == pro.id).Count(),
            //    pro.project_plans,
            //    pro.project_pic,
            //    pro.project_profile,
            //    //pro.project_remind,
            //    pro.isend,
            //    pro.endby,
            //    pro.endtime,
            //    pro.createtime
            //});
            return query;
        }

        /// <summary>
        /// Linq 关联查询详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public object GetDetails(string id)
        {
            //关联查询
            var query =
                from pro in _collection.AsQueryable()
                join province in _collection_sys_provinces.AsQueryable() on pro.project_province equals province.provincecode into provinceDefa
                join city in _collection_sys_city.AsQueryable() on pro.project_city equals city.citycode into cityDefa
                join dic_pro in _collection_sys_dictionaryvalue.AsQueryable() on pro.project_property equals dic_pro.id into dic_proDefa
                join dic_nur in _collection_sys_dictionaryvalue.AsQueryable() on pro.project_nature equals dic_nur.id into dic_nurDefa
                where pro.isdelete == 0 && pro.id == id
                //Pro_ProjectDetailsDto
                select new
                {
                    pro.id,
                    pro.project_name,
                    pro.project_shortname,
                    pro.project_province,
                    provincename = provinceDefa != null && provinceDefa.Count() > 0 ? provinceDefa.First().provincename : null,
                    pro.project_city,
                    cityname = cityDefa != null && cityDefa.Count() > 0 ? cityDefa.First().cityname : null,
                    pro.project_property,
                    protypename = dic_proDefa != null && dic_proDefa.Count() > 0 ? dic_proDefa.First().name : null, //项目属性
                    pro.project_nature,
                    naturename = dic_nurDefa != null && dic_nurDefa.Count() > 0 ? dic_nurDefa.First().name : null, //项目性质
                    //project_membernum = userlist.Where(p => p.projectid == pro.id).Count(),
                    pro.project_resperson,
                    pro.project_starttime,
                    pro.project_endtime,
                    //pro.project_cycle,
                    pro.project_order,
                    //pro.project_equipmentvariety,
                    //project_equipmentnum = equlist.Where(p => p.projectid == pro.id).Count(),
                    pro.project_plans,
                    pro.project_pic,
                    pro.project_profile,
                    //pro.project_remind,
                    pro.isend,
                    pro.endby,
                    pro.endtime,
                    pro.createtime
                };

            var info = query.FirstOrDefault();
            if (info != null)
            {
                var equlist = (from p in _collection_eqp_equipment_info.AsQueryable() where p.projectid == info.id && p.isdelete == 0 select p).ToList();
                var userlist = (from p in _collection_sys_user_account.AsQueryable() where p.projectlist.Contains(info.id) && p.delete_flag == false select p).ToList();

                var model = new 
                {
                    info.id,
                    info.project_name,
                    info.project_shortname,
                    info.project_province,
                    info.provincename,
                    info.project_city,
                    info.cityname,
                    info.project_property,
                    info.protypename, //项目属性
                    info.project_nature,
                    info.naturename, //项目性质
                    project_membernum = userlist.Count(),  //userData.Count(), //计算人员数量 by 项目id
                    info.project_resperson,
                    info.project_starttime,
                    info.project_endtime,
                    //info.project_cycle,
                    info.project_order,
                    //info.project_equipmentvariety,
                    project_equipmentnum = equlist.Count(), //计算设备数量 by 项目id
                    info.project_plans,
                    info.project_pic,
                    info.project_profile,
                    //info.project_remind,
                    info.isend,
                    info.endby,
                    info.endtime,
                    info.createtime
                };
                return model;
            }
            return null;
        }

        /// <summary>
        ///  删除项目 by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public void Delete(string id, UserAccountInfoModel userinfo)
        {
            #region 删除项目
            var prowhere = new List<FilterDefinition<Pro_Project_Info>>();
            prowhere.Add(Builders<Pro_Project_Info>.Filter.Eq("isdelete", 0));
            prowhere.Add(Builders<Pro_Project_Info>.Filter.Where(p => p.id == id));
            var proupdate = new List<UpdateDefinition<Pro_Project_Info>>();
            proupdate.Add(Builders<Pro_Project_Info>.Update.Set("isdelete", 1));
            proupdate.Add(Builders<Pro_Project_Info>.Update.Set("deleteby", userinfo.usercode));
            proupdate.Add(Builders<Pro_Project_Info>.Update.Set("deletetime", DateTime.Now));
            _collection.UpdateMany(Builders<Pro_Project_Info>.Filter.And(prowhere), Builders<Pro_Project_Info>.Update.Combine(proupdate));
            #endregion

            #region 删除楼层
            var flrwhere = new List<FilterDefinition<Sys_Floor>>();
            flrwhere.Add(Builders<Sys_Floor>.Filter.Eq("isdelete", 0));

            var blds = (from p in _collection_sys_buliding.AsQueryable() where p.projectid == id select p).Select(p => p.id).ToList();
            flrwhere.Add(Builders<Sys_Floor>.Filter.Where(p => blds.Contains(p.buildid)));
            var flrupdate = new List<UpdateDefinition<Sys_Floor>>();
            flrupdate.Add(Builders<Sys_Floor>.Update.Set("isdelete", 1));
            flrupdate.Add(Builders<Sys_Floor>.Update.Set("deleteby", userinfo.usercode));
            flrupdate.Add(Builders<Sys_Floor>.Update.Set("deletetime", DateTime.Now));
            _collection_sys_floor.UpdateMany(Builders<Sys_Floor>.Filter.And(flrwhere), Builders<Sys_Floor>.Update.Combine(flrupdate));
            #endregion

            #region 删除楼
            var bldwhere = new List<FilterDefinition<Sys_Building>>();
            bldwhere.Add(Builders<Sys_Building>.Filter.Eq("isdelete", 0));
            bldwhere.Add(Builders<Sys_Building>.Filter.Where(p => p.projectid == id));
            var bldupdate = new List<UpdateDefinition<Sys_Building>>();
            bldupdate.Add(Builders<Sys_Building>.Update.Set("isdelete", 1));
            bldupdate.Add(Builders<Sys_Building>.Update.Set("deleteby", userinfo.usercode));
            bldupdate.Add(Builders<Sys_Building>.Update.Set("deletetime", DateTime.Now));
            _collection_sys_buliding.UpdateMany(Builders<Sys_Building>.Filter.And(bldwhere), Builders<Sys_Building>.Update.Combine(bldupdate));
            #endregion

            #region 删除设备
            var equwhere = new List<FilterDefinition<Eqp_Equipment_Info>>();
            equwhere.Add(Builders<Eqp_Equipment_Info>.Filter.Eq("isdelete", 0));
            equwhere.Add(Builders<Eqp_Equipment_Info>.Filter.Where(p => p.projectid == id));
            var equupdate = new List<UpdateDefinition<Eqp_Equipment_Info>>();
            equupdate.Add(Builders<Eqp_Equipment_Info>.Update.Set("isdelete", 1));
            equupdate.Add(Builders<Eqp_Equipment_Info>.Update.Set("deleteby", userinfo.usercode));
            equupdate.Add(Builders<Eqp_Equipment_Info>.Update.Set("deletetime", DateTime.Now));
            _collection_eqp_equipment_info.UpdateMany(Builders<Eqp_Equipment_Info>.Filter.And(equwhere), Builders<Eqp_Equipment_Info>.Update.Combine(equupdate));
            #endregion

            #region 删除用户
            var userwhere = new List<FilterDefinition<Pro_Project_User>>();
            userwhere.Add(Builders<Pro_Project_User>.Filter.Eq("isdelete", 0));
            userwhere.Add(Builders<Pro_Project_User>.Filter.Where(p => p.projectid == id));
            var userupdate = new List<UpdateDefinition<Pro_Project_User>>();
            userupdate.Add(Builders<Pro_Project_User>.Update.Set("isdelete", 1));
            userupdate.Add(Builders<Pro_Project_User>.Update.Set("deleteby", userinfo.usercode));
            userupdate.Add(Builders<Pro_Project_User>.Update.Set("deletetime", DateTime.Now));
            _collection_pro_project_user.UpdateMany(Builders<Pro_Project_User>.Filter.And(userwhere), Builders<Pro_Project_User>.Update.Combine(userupdate));
            #endregion

        }

        /// <summary>
        /// 人员项目
        /// </summary>
        /// <param name="usercode">用户code</param>
        /// <returns></returns>
        public IEnumerable<object> GetUserProject(UserAccountInfoModel userinfo)
        {
            var query =
                from pro in _collection.AsQueryable()
                join province in _collection_sys_provinces.AsQueryable() on pro.project_province equals province.provincecode into provinceDefa
                join city in _collection_sys_city.AsQueryable() on pro.project_city equals city.citycode into cityDefa
                join dic_pro in _collection_sys_dictionaryvalue.AsQueryable() on pro.project_property equals dic_pro.id into dic_proDefa
                join dic_nur in _collection_sys_dictionaryvalue.AsQueryable() on pro.project_nature equals dic_nur.id into dic_nurDefa
                where pro.isdelete == 0
                orderby pro.createtime descending
                select new
                {
                    projectid = pro.id,
                    projectname = pro.project_name,
                    province = pro.project_province,
                    provincename = provinceDefa != null && provinceDefa.Count() > 0 ? provinceDefa.First().provincename : null,
                    city = pro.project_city,
                    cityname = cityDefa != null && cityDefa.Count() > 0 ? cityDefa.First().cityname : null,
                    protypeid = pro.project_property,
                    protypename = dic_proDefa != null && dic_proDefa.Count() > 0 ? dic_proDefa.First().name : null, //项目属性
                    natureid = pro.project_nature,
                    naturename = dic_nurDefa != null && dic_nurDefa.Count() > 0 ? dic_nurDefa.First().name : null //项目性质
                };
            if (userinfo.isallproject == 0)
                query = query.Where(it => userinfo.projectlist.Contains(it.projectid));

            return query;
        }

        /// <summary>
        /// 项目设备
        /// </summary>
        /// <param name="projectid">项目id</param>
        /// <returns></returns>
        public IEnumerable<object> GetProjectEquipment(string projectid)
        {
            //关联查询
            var bldinfo = (from bld in _collection_sys_buliding.AsQueryable() where bld.projectid == projectid && bld.isdelete == 0 select bld).ToList();
            var blrlist = bldinfo.Select(p => p.id).ToList();
            var flrinfo = (from flr in _collection_sys_floor.AsQueryable() where blrlist.Contains(flr.buildid) && flr.isdelete == 0 select flr).ToList();
            var flrlist = flrinfo.Select(p => p.id).ToList();
            var equinfo = (from equ in _collection_eqp_equipment_info.AsQueryable()
                           join dic in _collection_sys_dictionaryvalue.AsQueryable() on equ.systemid equals dic.id into info
                           where flrlist.Contains(equ.floorid) && equ.isdelete == 0
                           select new
                           {
                               equ.id,
                               equipmentname = equ.equipment_name,
                               equ.floorid,
                               equ.systemid,
                               systemname = info != null && info.Count() > 0 ? info.First().name : null
                           }).ToList();
            var list = bldinfo.Select(p => new
            {
                p.id,
                p.projectid,
                p.buildname,
                p.sortnum,
                items = flrinfo.Where(f => f.buildid == p.id).Select(f => new
                {
                    f.id,
                    f.buildid,
                    f.floorname,
                    f.sortnum,
                    items = equinfo.Where(e => e.floorid == f.id).Select(e => new
                    {
                        e.id,
                        e.floorid,
                        e.equipmentname,
                        e.systemid,
                        e.systemname
                    })
                }).OrderBy(f => f.sortnum)
            }).OrderBy(p => p.sortnum);

            return list;
        }

    }
}