using Furion.EventBus;

namespace BPA.MES.Base.Application.Services.WorkInfoService.Services
{
    /// <summary>
    /// 名    称 ：工单服务  
    /// 创 建 人 ：yangxiao  
    /// 创建时间 ：2023/7/20 14:39:41 
    /// 描    述 ：  
    /// </summary>
    [ApiDescriptionSettings("工单服务", Order = 0, Tag = "工单服务", Name = "WorkInfo", KeepName = true, SplitCamelCase = true, KeepVerb = true)]
    public class WorkInfoService : IWorkInfoService, ITransient, IDynamicApiController
    {
        private readonly ISqlSugarClient _dbContext;
        private readonly IMQTTService _MQTTService;
        public WorkInfoService(ISqlSugarClient db, IEventPublisher eventPublisher, IMQTTService MQTTService)
        {
            _dbContext = db;
            _MQTTService = MQTTService;
        }
        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost, OperLog("增加工单")]
        public async Task<bool> Add(WorkInfoAddInput input)
        {
            bool result = false;
            WorkInfoEntity entity = input.Adapt<WorkInfoEntity>();
            try
            {
                _dbContext.Ado.BeginTran();
                await _dbContext.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
                WorkInfoStatusEntity pztj_WorkInfoStatusEntity = new()
                {
                    Status = WorkOrderStatusEnum.Draft,
                    WorkId = entity.Id
                };
                await _dbContext.Insertable(pztj_WorkInfoStatusEntity).IgnoreColumns(true).ExecuteCommandAsync();
                _dbContext.Ado.CommitTran();
                result = true;
            }
            catch
            {
                _dbContext.Ado.RollbackTran();
                throw Oops.Bah("添加失败!");
            }
            return result;
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<bool> Del(WorkInfoDelInput input)
        {
            var res = await _dbContext.Deleteable<WorkInfoEntity>().Where(x => x.Id == input.Id).ExecuteCommandHasChangeAsync();
            return res;
        }
        /// <summary>
        /// 详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpGet]
        public async Task<WorkInfoDetailOutput> Detail(string Id)
        {
            var entity = await _dbContext.Queryable<WorkInfoEntity>()
                 .LeftJoin<FinalInfoEntity>((a, b) => a.FinalId == b.Id)
                 .LeftJoin<ProductLineEntity>((a, b, c) => a.LineId == c.Id)
                 .LeftJoin<WorkInfoStatusEntity>((a, b, c, d) => d.Id == SqlFunc.Subqueryable<WorkInfoStatusEntity>().Where(s => s.WorkId == a.Id).OrderByDesc(s => s.CreateTime).Select(s => s.Id))
                 .Where((a, b, c, d) => a.Id == Id)
                 .Select((a, b, c, d) => new WorkInfoDetailOutput
                 {
                     Id = a.Id.SelectAll(),
                     FinalName = b.Name,
                     LineName = c.Name,
                     Status = d.Status == null ? WorkOrderStatusEnum.Draft : d.Status
                 }).FirstAsync();
            if (entity==null)
            {
                throw Oops.Bah("没有找到工单信息!");
            }
            return entity;
        }
        /// <summary>
        /// 列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpGet]
        public async Task<List<WorkInfoOutput>> List(WorkInfoQueryInput input)
        {
            var entity = await _dbContext.Queryable<WorkInfoEntity>()
                 .LeftJoin<FinalInfoEntity>((a, b) => a.FinalId == b.Id)
                 .LeftJoin<ProductLineEntity>((a, b, c) => a.LineId == c.Id)
                 .LeftJoin<WorkInfoStatusEntity>((a, b, c, d) => d.Id == SqlFunc.Subqueryable<WorkInfoStatusEntity>().Where(s => s.WorkId == a.Id).OrderByDesc(s => s.CreateTime).Select(s => s.Id))
                 .WhereIF(!string.IsNullOrEmpty(input.Name), (a, b, c, d) => b.Name.Contains(input.Name))
                 .WhereIF(!string.IsNullOrEmpty(input.Id), (a, b, c, d) => a.Id.Contains(input.Id))
                 .Select((a, b, c, d) => new WorkInfoOutput
                 {
                     Id = a.Id.SelectAll(),
                     FinalName = b.Name,
                     LineName = c.Name,
                     Status = d.Status == null ? WorkOrderStatusEnum.Draft : d.Status
                 }).ToListAsync();
            return entity;
        }
        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<SqlSugarPagedList<WorkInfoOutput>> PagedList(WorkInfoQueryPageInput input)
        {
            var entity = await _dbContext.Queryable<WorkInfoEntity>()
                .LeftJoin<FinalInfoEntity>((a, b) => a.FinalId == b.Id)
                .LeftJoin<ProductLineEntity>((a, b, c) => a.LineId == c.Id)
                .LeftJoin<WorkInfoStatusEntity>((a, b, c, d) => d.Id == SqlFunc.Subqueryable<WorkInfoStatusEntity>().Where(s => s.WorkId == a.Id).OrderByDesc(s => s.CreateTime).Select(s => s.Id))
                .WhereIF(!string.IsNullOrEmpty(input.Name), (a, b, c, d) => b.Name.Contains(input.Name))
                .WhereIF(!string.IsNullOrEmpty(input.Id), (a, b, c, d) => a.Id.Contains(input.Id))
                .Select((a, b, c, d) => new WorkInfoOutput
                {
                    Id = a.Id.SelectAll(),
                    FinalName = b.Name,
                    LineName = c.Name,
                    Status = d.Status == null ? WorkOrderStatusEnum.Draft : d.Status
                })
                .ToPagedListAsync(input.PageIndex, input.PageSize);
            return entity;
        }
        /// <summary>
        /// 工单下发
        /// </summary>
        /// <param name="workId">工单id</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<bool> Publish(string workId)
        {

            var res = await UpdateStatus(
                    new WorkInfoStatusUpdateInput
                    {
                        WorkId = workId,
                        Status = WorkOrderStatusEnum.Issued
                    });
            var entity = await _dbContext.Queryable<WorkInfoEntity>().FirstAsync(x => x.Id == workId);
            if (res)
            {
                await _MQTTService.MqttPublish(entity, Topics.WorkOrderPush, MessageID.WorkOrderIssued);
            }
            return true;
        }
        /// <summary>
        /// 下拉
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpGet]
        public async Task<dynamic> SelectList()
        {
            var entity = await _dbContext.Queryable<WorkInfoEntity>().Select(x => new
            {
                key = x.Id,
                value = x.Name
            }).ToListAsync();
            return entity;
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<bool> Update(WorkInfoUpdateInput input)
        {
            WorkInfoEntity entity = input.Adapt<WorkInfoEntity>();
            var res = await _dbContext.Updateable(entity).IgnoreColumns(true).ExecuteCommandHasChangeAsync();
            return res;
        }
        /// <summary>
        /// 修改工单状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task<bool> UpdateStatus(WorkInfoStatusUpdateInput input)
        {
            WorkInfoStatusEntity entity = input.Adapt<WorkInfoStatusEntity>();
            var res = await _dbContext.Insertable(entity).IgnoreColumns(true).ExecuteCommandIdentityIntoEntityAsync();
            return res;
        }
        /// <summary>
        /// 强制结束工单
        /// </summary>
        /// <param name="workId"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<bool> ForcedEnd(string workId)
        {
            WorkInfoStatusEntity entity = new()
            {
                WorkId = workId,
                Status = WorkOrderStatusEnum.Completed
            };
            var res = await _dbContext.Insertable(entity).IgnoreColumns(true).ExecuteCommandIdentityIntoEntityAsync();
            return res;
        }
        /// <summary>
        /// 工单状态变更记录
        /// </summary>
        /// <param name="workId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<WorkInfoStatusOutput>> StatusList(string workId)
        {
            var entitys = await _dbContext.Queryable<WorkInfoStatusEntity>().Where(x => x.WorkId == workId).ToListAsync();
            List<WorkInfoStatusOutput> list = entitys.Adapt<List<WorkInfoStatusOutput>>();
            return list;
        }
    }
}
