using Mapster;
using MoYu.DependencyInjection;
using MoYu.FriendlyException;
using SafeCampus.Application.Services.Business;
using SafeCampus.Application.Services.Business.Warn.Dto;
using SafeCampus.Application.Services.Business.Warn.Service;

namespace SafeCampus.Web.Core.Controllers.Application.Business.Warn.Service;

public class WarnInfoService:DbRepository<WarnInfo>, IWarnInfoService,ITransient
{
    private readonly ISimpleCacheService _simpleCacheService;

    public WarnInfoService(ISimpleCacheService simpleCacheService)
    {
        _simpleCacheService = simpleCacheService;
    }

    public async Task<bool> Add(WarnInfoDto vm)
    {
        var model = vm.Adapt<WarnInfo>();
        await InsertAsync(model);
        return true;
    }


    public async Task<bool> Delete(long Id)
    {
        var model = await GetFirstAsync(x=>x.Id==Id);
        if (model == null)
        {
            throw Oops.Oh("信息不存在");
        }
        await DeleteAsync(model);
        return true;
    }

    public async Task<bool> Update(WarnInfoDto vm)
    {
        if (!vm.ID.HasValue)
        {
            throw Oops.Oh("请填写ID");
        }
        var model = await GetFirstAsync(p => p.Id == vm.ID);
        if (model == null)
        {
            throw Oops.Oh("信息不存在");
        }
        var res = vm.Adapt(model);
        await UpdateAsync(res);
        return true;
    }

    public async Task<WarnInfoDto> GetInfo(long Id)
    {
        var model = await Context.Queryable<WarnInfo>()
            .Includes(x=>x.CameraInfoItem)
            .Includes(x => x.PersonInfoItem)
            .Includes(x => x.PersonSetInfoItem)
            .FirstAsync(x => x.Id == Id);
        if (model == null)
        {
            throw Oops.Oh("信息不存在！");
        }
        return model.Adapt<WarnInfoDto>();
    }

    public async Task<SqlSugarPagedList<WarnInfoList>> GetList(WarnInfoSearch search)
    {
        var config = _simpleCacheService.Get<List<WarnGroupInfo>>(SafeCampusConst.WarnGroup);
        var guolvIds = new List<long>();
       
        if (config!=null)
        {
            var guolv = Context.Queryable<WarnInfo>();
            foreach (var warnGroupInfo in config)
            {
                if (warnGroupInfo.State)
                {
                    foreach (var warnGroupSubset in warnGroupInfo.Subset)
                    {
                        if (!warnGroupSubset.State)
                        {
                            guolvIds.AddRange(await guolv
                                .Where(x => warnGroupInfo.CameraId.Contains(x.CameraId) &&
                                            x.AlarmType == warnGroupSubset.Code).Select(x => x.Id).ToListAsync());
                        }
                    }
                }
                else
                {
                    guolvIds.AddRange(await guolv
                        .Where(x => warnGroupInfo.CameraId.Contains(x.CameraId)).Select(x => x.Id).ToListAsync());
                }
            }
        }
       
        var query = Context.Queryable<WarnInfo>()
            .Includes(x=>x.CameraInfoItem)
            .Includes(x=>x.PersonInfoItem)
            .Includes(x=>x.PersonSetInfoItem,x1=>x1.MajorInfoItem,x2=>x2.DepartmentInfoItem)
            .WhereIF(search.WarnHand.HasValue, x => x.WarnHand == search.WarnHand)
            .WhereIF(!string.IsNullOrEmpty(search.AlarmType),x => x.AlarmType == search.AlarmType)
            .WhereIF(!string.IsNullOrEmpty(search.CameraId), x => x.CameraId == search.CameraId)
            .WhereIF(search.StartTick.HasValue,x => x.Tick >= search.StartTick)
            .WhereIF(search.EndTick.HasValue, x => x.Tick <= search.EndTick)
            .WhereIF(guolvIds.Any(),x=>!guolvIds.Contains(x.Id));
                
        var list=await query.OrderByDescending(x=>x.Tick)
            .ToPagedListAsyncMapster<WarnInfo,WarnInfoList>(search.PageNum, search.PageSize);
        return  list;


    }

    public async Task<bool> HandWarn(HandWarnInput input)
    {
        var model = await GetFirstAsync(p => p.Id == input.Id);
        if (model == null)
        {
            throw Oops.Oh("信息不存在！");
        }
        model.Remark = input.Remark;
        model.WarnHand = 1;
        model.HandTime = DateTime.Now;
        await UpdateAsync(model);
        return true;
    }

    public async Task<List<WarnInfoList>> GetListNoPage(WarnInfoSearch search)
    {
        var query = Context.Queryable<WarnInfo>()
            .Includes(x => x.CameraInfoItem,x=>x.CameraGroupItem)
            .Includes(x => x.PersonInfoItem)
            .Includes(x => x.PersonSetInfoItem)
            .WhereIF(search.WarnHand.HasValue, x => x.WarnHand == search.WarnHand)
            .WhereIF(!string.IsNullOrEmpty(search.AlarmType), x => x.AlarmType == search.AlarmType)
            .WhereIF(search.AlarmTypes!=null&&search.AlarmTypes.Any(),x=>search.AlarmTypes.Contains(x.AlarmType))
            .WhereIF(search.PersonSetIds != null&&search.PersonSetIds.Any(),x=>search.PersonSetIds.Contains(x.PersonSetId))
            .WhereIF(search.CameraIds != null&&search.CameraIds.Any(),x=>search.CameraIds.Contains(x.CameraId))
            .WhereIF(!string.IsNullOrEmpty(search.CameraId), x => x.CameraId == search.CameraId)
            .WhereIF(!string.IsNullOrEmpty(search.PersonId), x => x.PersonId == search.PersonId)
            .WhereIF(search.StartTick.HasValue, x => x.Tick >= search.StartTick)
            .WhereIF(search.EndTick.HasValue, x => x.Tick <= search.EndTick);

        var list = await query.OrderByDescending(x => x.Tick)
            .ToListAsync();
        return list.Adapt<List<WarnInfoList>>();
    }
    public async Task<List<WarnType>>GetWarnType()
    {
        var query = Context.Queryable<WarnInfo>()
            .GroupBy(x => new { x.AlarmType, x.AlarmTypeDesc })
            .Select(xx => new WarnType
            {
                Name = xx.AlarmTypeDesc,
                Code = xx.AlarmType
            });
        return await query.ToListAsync();
    }
}