using Furion.DependencyInjection;
using Nirvana.Common;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Waste.Domain;

namespace Waste.Application
{
    /// <summary>
    /// 统计管理
    /// </summary>
    public class ReportService : BaseInfoService, IReportService, ITransient
    {
        private readonly ISqlSugarRepository<W_DeviceStatistics> repository;
        private readonly SqlSugarClient dbClient;

        public ReportService(ISqlSugarRepository<W_DeviceStatistics> sqlSugarRepository)
        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
        }
        /// <summary>
        /// 统计列表
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<PageParms<ReportList>> GetListAsync(QueryParams param)
        {
            RefAsync<int> totalnum = 0;
            var temquery = dbClient.Queryable<W_DeviceStatistics>();
            if (param.queryParam != null && param.queryParam.Count > 0)
            {
                List<IConditionalModel> conModels = new List<IConditionalModel>();
                param.queryParam.ForEach(x =>
                {
                    x.Value = x.Value.ToStr();
                    if (!string.IsNullOrEmpty(x.Value))
                    {
                        if(x.Name.ToLower() == "devname")
                        {
                            temquery = temquery.Where(e => SqlFunc.Subqueryable<W_Device>().Where(w => w.Name == x.Value && e.DevId == w.Id).Any());
                        }
                        else
                        {
                            conModels.Add(new ConditionalModel()
                            {
                                FieldName = x.Name,
                                ConditionalType = (ConditionalType)x.Type,
                                FieldValue = x.Value.Trim()
                            });
                        }
                    }
                });
                if (conModels.Count > 0)
                {
                    temquery = temquery.Where(conModels);
                }
            }
            if (currentUser.AccountType != (int)AccountType.platform)
            {
                temquery = temquery.Where(x => x.Businessid == currentUser.BusinessId);
            }
            string sorts = string.Format("{0} {1}", param.sort, param.order);
            var query = await temquery.OrderBy(sorts)
                .Select(x => new ReportList
                {
                    Id = x.Id,
                    Businessid = x.Businessid,
                    DevId = x.DevId,
                    CreateTime = x.CreateTime,
                    DayCount = x.DayCount,
                    DayPureWeight = x.DayPureWeight,
                    DayWeight = x.DayWeight,
                    WasteType = x.WasteType
                })
                .Mapper((it, cache) =>
                {
                    var allbus = cache.Get(list =>
                    {
                        var ids = list.Where(x => x.Businessid != Guid.Empty).Select(x => x.Businessid).ToList();
                        return repository.Change<W_Business>().Context.Queryable<W_Business>().Where(e => ids.Contains(e.Id)).ToList();
                    });
                    var bus = allbus.FirstOrDefault(x => x.Id == it.Businessid);
                    it.BusinessName = bus != null ? bus.Name : "";
                    var alldev = cache.Get(list =>
                    {
                        var ids = list.Where(x => x.DevId != Guid.Empty).Select(x => x.DevId).ToList();
                        return repository.Change<W_Device>().Context.Queryable<W_Device>().Where(e => ids.Contains(e.Id)).ToList();
                    });
                    var dev = alldev.FirstOrDefault(x => x.Id == it.DevId);
                    it.DevName = dev != null ? dev.Name : "";
                    it.DevCode = dev != null ? dev.Ecode : "";
                })
                 .ToPageListAsync(param.offset, param.limit, totalnum);
            return new PageParms<ReportList>
            {
                page = param.offset,
                Items = query,
                totalnum = totalnum,
                limit = param.limit
            };
        }
    }
}
