
using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Office.CustomUI;
using Infrastructure;
using NPOI.SS.Util;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.Interface;
using OpenAuth.App.Request;
using OpenAuth.App.Response;
using OpenAuth.App.ServiceApp.MiManager.Request;
using OpenAuth.App.ServiceApp.Request;
using OpenAuth.App.ServiceApp.Response;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using SqlSugar;

namespace OpenAuth.App
{
    public class MiViolationReportApp : SqlSugarBaseApp<MiViolationReport, SugarDbContext>
    {
        public MiViolationReportApp(
            ISugarUnitOfWork<SugarDbContext> unitWork,
            ISimpleClient<MiViolationReport> repository,
            IAuth auth
            ) : base(unitWork, repository, auth)
        {

        }

        #region 查询
        /// <summary>
        /// 分页
        /// </summary>
        public async Task<Response<PageInfo<List<dynamic>>>> LoadAllPage(MiviolationReq req)
        {
            RefAsync<int> totalCount = 0;
            var user = _auth.GetCurrentUser();
            var users = user.User;
            var level = user.Orgs?.Min(x => x.Level);
            //如果不是超级管理员
            if (user != null && (users.Id == -1 || level == 0))
            {
                var list = await base.Repository.AsQueryable()
                    .Where(p => p.IsDelete == false)
                    .WhereIF(req.begindate != null && req.enddate != null, p => p.ReportTime >= req.begindate && p.ReportTime < req.enddate)
                    .WhereIF(req.status != null, p => p.Status == req.status)
                    .WhereIF(!string.IsNullOrEmpty(req.key), p => p.Title.Contains(req.key))
                    .WhereIF(req.viotype != null, p => p.ViolationType == req.viotype)
                    .LeftJoin<MiMinePoint>((p, m) => p.MinePointId == m.Id)
                    .LeftJoin<SysUser>((p, m, u) => p.Reporter == u.Id.ToString())
                    .LeftJoin<SysUser>((p,m,u,s)=>p.Handler==s.Id.ToString())
                    .LeftJoin<SysOrg>((p, m, u, s, o) => p.ReportUnit == o.Id.ToString())
                    .LeftJoin<SysOrg>((p, m, u, s, o,d) => p.HandlingUnit == d.Id.ToString())
                    .WhereIF(!string.IsNullOrEmpty(req.pointname), (p, m, u, s, o, d) => m.Name.Contains(req.pointname))
                    .OrderBy((p, m, u, s, o, d) => p.Status)
                    .OrderByDescending((p, m, u, s, o, d) => p.ReportTime)
                    .Select<dynamic>((p, m, u, s, o, d) => new
                    {
                        Id = p.Id.SelectAll(),
                        ReportUserName = u.Name,
                        PointName = m.Name,
                        OrgName = o.Name,
                        HandelUserName=s.Name,
                        HandelUnit=d.Name
                    })
                    .ToPageListAsync(req.page, req.limit, totalCount);
                return new Response<PageInfo<List<dynamic>>>
                {
                    Result = new PageInfo<List<dynamic>>
                    {
                        Items = list,
                        Total = totalCount
                    }
                };
            }
            else
            {
                if (user.Orgs.Count == 0 || level == null)
                {
                    throw new Exception("无权限查看数据");
                }
                else
                {
                    //查询所有子部门
                    List<string> orgidlist = new List<string>();
                    var orgs = user.Orgs?.Select(r => r.Id).ToList();
                    using (var uow = base.UnitWork.CreateContext())
                    {
                        foreach (var item in orgs)
                        {
                            //orgidlist.Add(item.ToString());
                            var allchilds = uow.SysOrg.AsQueryable().ToChildList(r => r.ParentId, item);
                            if (allchilds.Count > 0)
                            {
                                orgidlist = orgidlist.Concat(allchilds.Select(r => r.Id.ToString())).ToList();
                            }
                        }

                        var list = await uow.MiViolationReport.AsQueryable()
                            .Where(p => p.IsDelete == false)
                            .WhereIF(req.begindate != null && req.enddate != null, p => p.ReportTime >= req.begindate && p.ReportTime < req.enddate)
                            .WhereIF(req.status != null, p => p.Status == req.status)
                            .WhereIF(!string.IsNullOrEmpty(req.key), p => p.Title.Contains(req.key))
                            .WhereIF(req.viotype != null, p => p.ViolationType == req.viotype)
                            .Where(p => orgidlist.Contains(p.ReportUnit) || orgidlist.Contains(p.HandlingUnit) || p.Reporter == user.User.Id.ToString() || p.Handler==user.User.Id.ToString())
                            .LeftJoin<MiMinePoint>((p, m) => p.MinePointId == m.Id)
                            .LeftJoin<SysUser>((p, m, u) => p.Reporter == u.Id.ToString())
                            .LeftJoin<SysUser>((p, m, u, s) => p.Handler == s.Id.ToString())
                            .LeftJoin<SysOrg>((p, m, u, s, o) => p.ReportUnit == o.Id.ToString())
                            .LeftJoin<SysOrg>((p, m, u, s, o, d) => p.HandlingUnit == d.Id.ToString())
                            .WhereIF(!string.IsNullOrEmpty(req.pointname), (p, m, u, s, o, d) => m.Name.Contains(req.pointname))
                            .OrderBy((p, m, u, s, o, d) => p.Status)
                            .OrderByDescending((p, m, u, s, o, d) => p.ReportTime)
                            .Select<dynamic>((p, m, u, s, o, d) => new
                            {
                                Id = p.Id.SelectAll(),
                                ReportUserName = u.Name,
                                PointName = m.Name,
                                OrgName = o.Name,
                                HandelUserName = s.Name,
                                HandelUnit = d.Name
                            })
                            .ToPageListAsync(req.page, req.limit, totalCount);

                        return new Response<PageInfo<List<dynamic>>>
                        {
                            Result = new PageInfo<List<dynamic>>
                            {
                                Items = list,
                                Total = totalCount
                            }
                        };
                    }
                }
            }
        }
        #endregion

        public async Task<dynamic> Get(string id)
        {
            using (var uow = base.UnitWork.CreateContext())
            {
                var result = await base.Repository.AsQueryable()
                  .Where(p => p.Id == id)
                  .LeftJoin<SysOrg>((p, r) => p.ReportUnit == r.Id.ToString())
                  .LeftJoin<MiMinePoint>((p, r, m) => p.MinePointId == m.Id)
                  .LeftJoin<MiParking>((p, r, m, pk) => p.ParkingId == pk.Id)
                  .LeftJoin<SysUser>((p, r, m, pk,u) => p.Reporter == u.Id.ToString())
                  .LeftJoin<SysUser>((p, r, m, pk, u, u2) => p.Handler == u2.Id.ToString())
                  .LeftJoin<SysOrg>((p, r, m, pk, u, u2,o)=>p.HandlingUnit==o.Id.ToString())
                  .Select((p, r, m, pk, u, u2, o) => new
                  {
                      // 提车信息
                      ReporterName = u.Name,
                      HandlerName = u2.Name,
                      ReportUnitName=r.Name,
                      HandUnitName=o.Name,

                      // 违法上报信息
                      p.Id,
                      p.Title,
                      ReportStatus = p.Status,
                      p.PartyName,
                      p.PartyPhone,
                      p.ViolationType,
                      p.ProblemDescription,
                      p.HandlingOpinion,
                      p.HandlingUnit,
                      p.Handler,
                      p.HandlingTime,
                      p.ReportTime,
                      p.Reporter,
                      p.ReportUnit,
                      p.Lng,
                      p.Lat,
                        p.StatusName,
                        p.ViolationTypeName,
                        p.MineralTypes,
                      // 盗采点信息
                      MinePointId = m.Id,
                      MinePointName = m.Name,
                      m.CountyName,
                      MinePointLng = m.Lng,
                      MinePointLat = m.Lat,
                      // 停车场信息
                      ParkingId = pk.Id,
                      ParkingCode = pk.Num,
                      ParkingName = pk.Name,
                      pk.Phone,
                      pk.Address
                  })
                  .FirstAsync();

                if (result == null)
                    return null;

                // 查询车辆信息
                var vehicles = await uow.MiVehicle.AsQueryable()
                    .Where(v => v.ViolationReportId == result.Id)
                    .ToListAsync();

                // 查询车辆图片
                List<MiVehicleImage> vehicleImages = new List<MiVehicleImage>();
                if (vehicles.Any())
                {
                    var vehicleIds = vehicles.Select(v => v.Id).ToList();
                    vehicleImages = await uow.MiVehicleImage.AsQueryable()
                        .Where(vi => vehicleIds.Contains(vi.VehicleId))
                        .ToListAsync();
                }

                // 查询现场照片
                var scenePhotos = await uow.MiScenePhoto.AsQueryable()
                    .Where(sp => sp.ViolationReportId == result.Id)
                    .ToListAsync();

                //查询其他人员
                var otherPersons=await uow.MiViolationUsers.AsQueryable()
                    .Where(r=>r.ViolationReportId==result.Id)
                    .ToListAsync();

                return new
                {
                    ViolationReport = new
                    {
                        result.Id,
                        result.Title,
                        Status=result.ReportStatus,
                        result.PartyName,
                        result.PartyPhone,
                        result.ViolationType,
                        result.ProblemDescription,
                        result.HandlingOpinion,
                        result.HandlingUnit,
                        result.Handler,
                        result.HandlingTime,
                        result.ReportTime,
                        result.Reporter,
                        result.ReporterName,
                        result.HandlerName,
                        result.ReportUnit,
                        result.ReportUnitName,
                        result.Lng,
                        result.Lat,
                        result.StatusName,
                        result.ViolationTypeName,
                        result.HandUnitName,
                        result.MineralTypes
                    },

                    MinePoint = string.IsNullOrEmpty(result.MinePointId) ? null : new
                    {
                        result.MinePointId,
                        result.MinePointName,
                        result.CountyName,
                        result.MinePointLng,
                        result.MinePointLat
                    },
                    Parking = string.IsNullOrEmpty(result.ParkingId) ? null : new
                    {
                        result.ParkingId,
                        result.ParkingCode,
                        result.ParkingName,
                        result.Phone,
                        result.Address
                    },
                    Vehicles = vehicles.Select(v => new
                    {
                        v.Id,
                        v.LicensePlate,
                        v.Type,
                        v.Name,
                        v.IdCard,
                        v.Phone,
                        v.TypeName,
                        v.Remark,
                        v.State,
                        VehicleImages = vehicleImages
                            .Where(img => img.VehicleId == v.Id)
                            .Select(img => new
                            {
                                img.Id,
                                img.Image,
                                img.Lng,
                                img.Lat,
                                img.Angle,
                                img.CreateTime
                            })
                            .ToList()
                    }).ToList(),

                    ScenePhotos = scenePhotos.Select(sp => new
                    {
                        sp.Id,
                        sp.Image,
                        sp.Lng,
                        sp.Lat,
                        sp.Angle,
                        sp.CreateTime
                    }).ToList(),
                    OtherPersons=otherPersons.ToList()
                };
            }
        }


        /// <summary>
        /// 添加
        /// </summary>
        public async Task<Response<bool>> Add(MiViolationReport model)
        {
            var flag = await Repository.InsertAsync(model);

            return new Response<bool>
            {
                Result = flag,
                Message = flag == true ? "success" : "error"
            };
        }



        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="ids"></param>
        public async Task<Response<bool>> Delete(List<string> ids)
        {
            using (var uow = base.UnitWork.CreateContext())
            {
                await uow.MiViolationReport.UpdateSetColumnsTrueAsync(a => new MiViolationReport
                {
                    IsDelete = true
                }, a => ids.Contains(a.Id));

                var flag=uow.Commit();

                return new Response<bool>
                {
                    Result = flag,
                    Message = flag ? "success" : "error"
                };
            }
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="obj"></param>
        public async Task<Response<bool>> Update(MiViolationReport model)
        {
            bool flag = await base.Repository.UpdateAsync(model);

            return new Response<bool>
            {
                Result = flag,
                Message = flag == true ? "success" : "error"
            };
        }

        /// <summary>
        /// 事务示例
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<Response<bool>> AssignModule()
        {
            using (var uwo = UnitWork.CreateContext())
            {
                //await uwo.SysRoleElement.InsertRangeAsync(model.ElementIds.Select(a => new SysRoleElement { RoleId = model.RoleId, ElementId = a }).ToList());

                var flag = uwo.Commit();
                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "success" : "error"
                };
            }
        }

        /// <summary>
        /// 上报违法
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<Response<bool>> Report(MiViolationReportRequest request)
        {
            using (var uwo = UnitWork.CreateContext())
            {
                var user=_auth.GetCurrentUser();
                var org=user.Orgs.FirstOrDefault();
                if (org == null)
                {
                    throw new Exception("请先分配部门");
                }
                //上报信息
                var model = request.MapTo<MiViolationReport>();
                model.Id = Guid.NewGuid().ToString();
                model.Status = 0;
                model.StatusName = "待处理";
                model.ReportTime = DateTime.Now;
                model.Reporter=user.User.Id.ToString();
                model.IsDelete = false;
                model.ReportUnit=org.Id.ToString();

                //现场照片
                var photos = request.SencePhotos.MapToList<MiScenePhoto>();
                photos.ForEach(a =>
                {
                    a.Id = Guid.NewGuid().ToString();
                    a.ViolationReportId = model.Id;
                    a.CreateTime = DateTime.Now;
                });

                //其他人员
                var others = request.OtherPersons.MapToList<MiViolationUsers>();
                others.ForEach(a =>
                {
                    a.Id = Guid.NewGuid().ToString();
                    a.ViolationReportId = model.Id;
                });

                var vehicleList = new List<MiVehicle>();
                var vehicleImageList = new List<MiVehicleImage>();
                foreach (var item in request.Vehicles)
                {
                    //车辆信息
                    var vehicle = item.MapTo<MiVehicle>();
                    vehicle.Id = Guid.NewGuid().ToString();
                    vehicle.ViolationReportId = model.Id;
                    vehicle.CreateTime=DateTime.Now;
                    vehicle.State = 0;    //初始默认未提车

                    //车辆图片
                    var images = item.VehicleImages.MapToList<MiVehicleImage>();
                    images.ForEach(a =>
                    {
                        a.Id = Guid.NewGuid().ToString();
                        a.ViolationReportId = model.Id;
                        a.ParkingId = model.ParkingId;
                        a.VehicleId = vehicle.Id;
                        a.CreateTime = DateTime.Now;
                        vehicleImageList.Add(a);

                    });

                    vehicleList.Add(vehicle);
                }

                await uwo.MiViolationReport.InsertAsync(model);
                await uwo.MiScenePhoto.InsertRangeAsync(photos);
                await uwo.MiViolationUsers.InsertRangeAsync(others);   //其他人员
                await uwo.MiVehicle.InsertRangeAsync(vehicleList);
                await uwo.MiVehicleImage.InsertRangeAsync(vehicleImageList);


                var flag = uwo.Commit();
                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "success" : "error"
                };
            }
        }

        public async Task<Response<bool>> ReportHandle(HandleInfo info)
        {
            var user = _auth.GetCurrentUser().User;

            var level = _auth.GetCurrentUser().Orgs.Min(a => a.Level);
            //路径
            var org = _auth.GetCurrentUser().Orgs.FirstOrDefault();
            if (org == null)
            {
                throw new Exception("请先分配部门");
            }
            int count = await base.Repository.AsUpdateable().SetColumns(
                a => new MiViolationReport
                {
                    HandlingOpinion = info.HandlingOpinion,
                    HandlingTime = DateTime.Now,
                    HandlingUnit = org.Id.ToString(),
                    Handler=user.Id.ToString(),                   
                    Status=1,
                    StatusName="已处理"
                }).Where(a => a.Id == info.Id).ExecuteCommandAsync();

            return new Response<bool>
            {
                Result = count > 0,
                Message = count > 0 ? "success" : "error"
            };
        }
    }
}