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

namespace EquipmentApi.Repositories
{
    public class Wo_WashRepository : BaseRepository<Wo_Wash, string>, IWo_WashRepository
    {
        protected readonly ILogger<BaseRepository<Wo_Wash, string>> _logger;
        protected readonly IMongoCollection<Pro_Project_Info> _collection_pro_project_info;
        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_Floor> _collection_sys_floor;
        public Wo_WashRepository(IOptions<MongodbOptions> settings, ILogger<BaseRepository<Wo_Wash, string>> logger) : base(settings, logger)
        {
            _collection_pro_project_info = _context.GetCollection<Pro_Project_Info>();//获取集合
            _collection_sysdepartment = _context.GetCollection<Sys_Department>();
            _collection_sys_provinces = _context.GetCollection<Sys_Provinces>();
            _collection_sys_city = _context.GetCollection<Sys_City>();
            _collection_sys_floor = _context.GetCollection<Sys_Floor>();
            _logger = logger;
        }

        /// <summary>
        /// Lookup 关联查询 分页 demo
        /// </summary>
        /// <param name="match"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sort"></param>
        /// <returns></returns>
        public IEnumerable<Wo_WashListDto> GetList1(BsonDocument match, int pageIndex, int pageSize, BsonDocument sort)
        {
            try
            {
                //可限制返回的文档中的字段或者重命名其中的字段
                #region BsonDocument model
                var project = new BsonDocument{
                                { "_id",0},
                                { "wocode",1},
                                { "channel",1},
                                { "projectid",1},
                                { "provincecode",1},
                                { "citycode",1},
                                { "departmentsid",1},
                                { "floorid",1},
                                { "personid",1},
                                { "tasktype",1},
                                { "createtime",1},
                                { "tasktime",1},
                                { "batchesnumber",1},
                                { "bigsheetnum",1},
                                { "quiltcovernum",1},
                                { "pillowcasenum",1},
                                { "pillownum",1},
                                { "clothesnum",1},
                                { "pantsnum",1},
                                { "whitepatientclothesnum",1},
                                { "whitepatientpantsnum",1},
                                { "singlelayer",1},
                                { "doublelayer",1},
                                { "quiltnum",1},
                                { "matnum",1},
                                { "coolquiltnum",1},
                                { "bedspreadnum",1},
                                { "blindsnum ",1},
                                { "workclothesnum",1},
                                { "nurseclothesnum",1},
                                { "nursepantnum",1},
                                { "constraintsnum",1},
                                { "hatsnum",1},
                                { "project_name","$pp.project_name"},
                                { "departmenname","$dd.departmenname"},
                                { "floorname","$ff.floorname"}
                            };
                #endregion

                return BsonSerializer.Deserialize<IEnumerable<Wo_WashListDto>>(_collection.Aggregate()
                .Lookup("pro_project_info", "projectid", "_id", "ttttt")
                .Lookup("sys_department", "departmentsid", "_id", "dd")
                .Lookup("sys_floor", "floorid", "_id", "ff")
                .Match(match)
                .Sort(sort)
                .Project(project)
                .Skip((pageIndex - 1) * pageSize)
                .Limit(pageSize).ToList().ToJson());
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                throw ex;
            }
        }

        /// <summary>
        /// Lookup 关联查询 分页 demo
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IEnumerable<BsonDocument> GetList2(int pageIndex, int pageSize)
        {
            try
            {
                //可限制返回的文档中的字段或者重命名其中的字段
                #region BsonDocument model
                var project = new BsonDocument{
                                { "_id",0},
                                { "wocode",1},
                                { "channel",1},
                                { "projectid",1},
                                { "provincecode",1},
                                { "citycode",1},
                                { "departmentsid",1},
                                { "floorid",1},
                                { "personid",1},
                                { "tasktype",1},
                                { "createtime",1},
                                { "tasktime",1},
                                { "batchesnumber",1},
                                { "bigsheetnum",1},
                                { "quiltcovernum",1},
                                { "pillowcasenum",1},
                                { "pillownum",1},
                                { "clothesnum",1},
                                { "pantsnum",1},
                                { "whitepatientclothesnum",1},
                                { "whitepatientpantsnum",1},
                                { "singlelayer",1},
                                { "doublelayer",1},
                                { "quiltnum",1},
                                { "matnum",1},
                                { "coolquiltnum",1},
                                { "bedspreadnum",1},
                                { "blindsnum ",1},
                                { "workclothesnum",1},
                                { "nurseclothesnum",1},
                                { "nursepantnum",1},
                                { "constraintsnum",1},
                                { "hatsnum",1},
                                { "project_name","$pp.project_name"},
                                { "departmenname","$dd.departmenname"},
                                { "floorname","$ff.floorname"}
                            };
                #endregion

                //条件
                //var match = new BsonDocument
                //            {
                //                {"wocode", new BsonDocument
                //                                   {
                //                                       {
                //                                           "$eq", "1522224862706"
                //                                       }
                //                                   }}
                //            };
                var tt = new BsonDocument
                            {
                                {"wocode", 1 }
                            };
                var match = new BsonDocument
                            {
                                {"wocode", tt }
                            };

                //排序
                var sort = new BsonDocument {
                    { "wocode", 1 }
                };

                return _collection.Aggregate()
                .Lookup("pro_project_info", "projectid", "_id", "ttttt")
                .Lookup("sys_department", "departmentsid", "_id", "dd")
                .Lookup("sys_floor", "floorid", "_id", "ff")
                .Match(match)
                .Sort(sort)
                .Project(project)
                .Skip((pageIndex - 1) * pageSize)
                .Limit(pageSize).ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                throw ex;
            }
        }

        /// <summary>
        /// Linq 关联查询 分页
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IEnumerable<WoWashDto> GetListsByPage(string keyword, string stime, string etime, int pageIndex, int pageSize, out int recordCount)
        {
            //关联查询
            var query =
                from wash in _collection.AsQueryable()
                join dep in _collection_sysdepartment.AsQueryable() on wash.departmentsid equals dep.id into depDefa
                join proje in _collection_pro_project_info.AsQueryable() on wash.projectid equals proje.id into projeDefa
                join province in _collection_sys_provinces.AsQueryable() on wash.provincecode equals province.provincecode into provinceDefa
                join city in _collection_sys_city.AsQueryable() on wash.citycode equals city.citycode into cityDefa
                join fl in _collection_sys_floor.AsQueryable() on wash.floorid equals fl.id into flDefa
                where wash.isdelete == 0
                orderby wash.createtime descending
                select new WoWashDto
                {
                    id = wash.id,
                    wocode = wash.wocode,
                    channel = wash.channel,
                    projectid = wash.projectid,
                    provincecode = wash.provincecode,
                    citycode = wash.citycode,
                    personid = wash.personid,
                    tasktype = wash.tasktype,
                    tasktime = wash.tasktime,
                    batchesnumber = wash.batchesnumber,
                    //channelname = Enum.GetName(typeof(Enumchannel), wash.channel),
                    projectname = projeDefa != null && projeDefa.Count()>0 ? projeDefa.First().project_name : null,
                    provincename = provinceDefa != null && provinceDefa.Count()>0 ? provinceDefa.First().provincename : null,
                    cityname = cityDefa != null && cityDefa.Count()>0 ? cityDefa.First().cityname : null,
                    departmentsid = wash.departmentsid,
                    departmentsname = depDefa != null && depDefa.Count()>0 ? depDefa.First().departmenname : null,
                    floorid = wash.floorid,
                    floorname = flDefa != null && flDefa.Count()>0 ? flDefa.First().floorname : null,
                    createtime = wash.createtime
                };
            #region 查询条件
            if (!string.IsNullOrEmpty(keyword))
                query = query.Where(it => it.wocode.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 list = query.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return list;
        }

        /// <summary>
        /// Linq 关联查询详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public WoWashDetailsDto GetDetails(string id)
        {
            //关联查询
            var query =
                from wash in _collection.AsQueryable()
                join dep in _collection_sysdepartment.AsQueryable() on wash.departmentsid equals dep.id into depDefa
                join proje in _collection_pro_project_info.AsQueryable() on wash.projectid equals proje.id into projeDefa
                join province in _collection_sys_provinces.AsQueryable() on wash.provincecode equals province.provincecode into provinceDefa
                join city in _collection_sys_city.AsQueryable() on wash.citycode equals city.citycode into cityDefa
                join fl in _collection_sys_floor.AsQueryable() on wash.floorid equals fl.id into flDefa
                where wash.isdelete == 0 && wash.id == id
                select new WoWashDetailsDto
                {
                    id = wash.id,
                    wocode = wash.wocode,
                    channel = wash.channel,
                    projectid = wash.projectid,
                    provincecode = wash.provincecode,
                    citycode = wash.citycode,
                    projectname = projeDefa != null && projeDefa.Count() > 0 ? projeDefa.First().project_name : null,
                    provincename = provinceDefa != null && provinceDefa.Count() > 0 ? provinceDefa.First().provincename : null,
                    cityname = cityDefa != null && cityDefa.Count() > 0 ? cityDefa.First().cityname : null,
                    departmentsid = wash.departmentsid,
                    departmentsname = depDefa != null && depDefa.Count() > 0 ? depDefa.First().departmenname : null,
                    floorid = wash.floorid,
                    floorname = flDefa != null && flDefa.Count() > 0 ? flDefa.First().floorname : null,
                    createtime = wash.createtime,
                    isdelete = wash.isdelete,    //                
                    personid = wash.personid,
                    tasktype = wash.tasktype,
                    batchesnumber = wash.batchesnumber,
                    tasktime = wash.tasktime,
                    bigsheetnum = wash.bigsheetnum,
                    quiltcovernum = wash.quiltcovernum,
                    pillowcasenum = wash.pillowcasenum,
                    pillownum = wash.pillownum,
                    clothesnum = wash.clothesnum,
                    pantsnum = wash.pantsnum,
                    whitepatientclothesnum = wash.whitepatientclothesnum,
                    whitepatientpantsnum = wash.whitepatientpantsnum,
                    singlelayer = wash.singlelayer,
                    doublelayer = wash.doublelayer,
                    quiltnum = wash.quiltnum,
                    matnum = wash.matnum,
                    coolquiltnum = wash.coolquiltnum,
                    bedspreadnum = wash.bedspreadnum,
                    blindsnum = wash.blindsnum,
                    workclothesnum = wash.workclothesnum,
                    nurseclothesnum = wash.nurseclothesnum,
                    nursepantnum = wash.nursepantnum,
                    constraintsnum = wash.constraintsnum,
                    hatsnum = wash.hatsnum,
                    createby = wash.createby,
                };
            //var model = await query.FirstOrDefault(wash => wash.isdelete == 0 && wash.id == id);
            var model = query.FirstOrDefault();
            if (model != null) {
                return model;
            }
            return null;
        }

        /// <summary>
        /// Linq 关联查询 分页 - App
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IEnumerable<WoWashDto> GetAppLists(string keyword, string projectid, string departmentsid, string floorid, string personid, string createtime, int tasktype)
        {
            //关联查询
            var query =
                from wash in _collection.AsQueryable()
                join dep in _collection_sysdepartment.AsQueryable() on wash.departmentsid equals dep.id into depDefa
                join proje in _collection_pro_project_info.AsQueryable() on wash.projectid equals proje.id into projeDefa
                join province in _collection_sys_provinces.AsQueryable() on wash.provincecode equals province.provincecode into provinceDefa
                join city in _collection_sys_city.AsQueryable() on wash.citycode equals city.citycode into cityDefa
                join fl in _collection_sys_floor.AsQueryable() on wash.floorid equals fl.id into flDefa
                where wash.isdelete == 0
                orderby wash.createtime
                select new WoWashDto
                {
                    id = wash.id,
                    wocode = wash.wocode,
                    channel = wash.channel,
                    projectid = wash.projectid,
                    provincecode = wash.provincecode,
                    citycode = wash.citycode,
                    departmentsid = wash.departmentsid,
                    floorid = wash.floorid,
                    personid = wash.personid,
                    tasktype = wash.tasktype,
                    tasktime = wash.tasktime,
                    batchesnumber = wash.batchesnumber,
                    projectname = projeDefa != null ? projeDefa.First().project_name : null,
                    provincename = provinceDefa != null ? provinceDefa.First().provincename : null,
                    cityname = cityDefa != null ? cityDefa.First().cityname : null,
                    departmentsname = depDefa != null ? depDefa.First().departmenname : null,
                    floorname = flDefa != null ? flDefa.First().floorname : null,
                    createtime = wash.createtime
                };
            #region 查询条件
            if (!string.IsNullOrEmpty(keyword))
                query = query.Where(it => it.wocode.Contains(keyword));
            if (!string.IsNullOrEmpty(projectid))
                query = query.Where(it => it.projectid == projectid);
            if (!string.IsNullOrEmpty(departmentsid))
                query = query.Where(it => it.departmentsid == departmentsid);
            if (!string.IsNullOrEmpty(floorid))
                query = query.Where(it => it.floorid == floorid);
            if (!string.IsNullOrEmpty(personid))
                query = query.Where(it => it.personid == personid);
            if (tasktype > 0)
                query = query.Where(it => it.tasktype == tasktype);
            
            //时间查询
            if (!string.IsNullOrEmpty(createtime))
            {
                string stime = createtime + "00:00:00";
                string etime = createtime + "23:59:59";
                query = query.Where(it => it.createtime >= Convert.ToDateTime(stime));
                query = query.Where(it => it.createtime <= Convert.ToDateTime(etime));
            }
            #endregion
            var list = query;
            return list;
        }
    }
}
