using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Enums.PF;
using APT.BaseData.Domain.IServices;
using APT.BaseData.Domain.IServices.FM;
using APT.Infrastructure.Core;
using APT.MS.Domain.Entities.SC.PR;
using APT.MS.Domain.Enums;
using APT.Utility;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using System;
using APT.BaseData.Domain.Entities.FM;
using InfluxData.Net.InfluxDb.Models.Responses;
using NPOI.SS.Formula.Functions;
using APT.MS.Domain.ApiModel.SC.PR;

namespace APT.SC.WebApi.Controllers.Api.PRController
{
    /// <summary>
    ///  药品出库记录表
    /// </summary>
    [Route("api/PR/PRDrugOutboundRecord")]
    public partial class DrugOutboundRecordController : AuthorizeApiController<T_PR_DRUG_OUTBOUND_RECORD>
    {
        IPFCodeRuleService CodeRuleService { get; set; }
        IFMNotificationTaskService NotificationTaskService { get; set; }
        IFMFlowPermitService MFlowPermitService { get; set; }
        IPFApproveCallBackService ApproveCallBackService { get; set; }
        /// <summary>
        /// 药品出库记录表
        /// </summary>
        /// <param name="notificationTaskService"></param>
        public DrugOutboundRecordController(IPFCodeRuleService codeRuleService, IFMNotificationTaskService notificationTaskService, IFMFlowPermitService mFlowPermitService, IPFApproveCallBackService approveCallBackService)
        {
            CodeRuleService = codeRuleService;
            NotificationTaskService = notificationTaskService;
            MFlowPermitService = mFlowPermitService;
            ApproveCallBackService = approveCallBackService;
        }
        /// <summary>
        /// 新增/编辑
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        [HttpPost, Route("FullUpdate")]
        public JsonActionResult<bool> FullUpdate([FromBody] T_PR_DRUG_OUTBOUND_RECORD entity)
        {
            return SafeExecute(() =>
            {
                if (string.IsNullOrEmpty(entity.CODE))
                    entity.CODE = DateTime.Now.Year.ToString().PadLeft(4, '0') + DateTime.Now.Month.ToString().PadLeft(2, '0') + DateTime.Now.Day.ToString().PadLeft(2, '0') + new Random().Next(9999).ToString().PadLeft(4, '0');
                entity.TIME = DateTime.Now;
                entity.STATUS = PFStandardStatus.Draft;
                var loginUserId = APT.Infrastructure.Api.AppContext.CurrentSession.UserID;
                if (entity.TaskID != Guid.Empty)
                {
                    var currTask = GetEntity<T_FM_NOTIFICATION_TASK>(t => t.ID == entity.TaskID);
                    if (currTask != null)
                    {
                        loginUserId = currTask.USER_ID;
                    }
                }
                entity.USER_ID = loginUserId;
                var user = this.GetEntity<T_FM_USER>(t => t.ID == loginUserId.Value && t.ENABLE_STATUS == 0);
                entity.DEPARTMENT_ID = user?.DEPARTMENT_ID;
                var details = entity.Nav_Details;
                entity.Nav_Details = null;
                if (details != null && details.Any())
                {
                    details.ForEach(t =>
                    {
                        t.ORG_ID = entity.ORG_ID; t.OUTBOUND_RECORD_ID = entity.ID;
                    });
                }
                T_FM_NOTIFICATION_TASK notice = null;
                T_PR_DRUG_CARRY_RECORD carry = null;
                List<T_PR_DRUG_CARRY_RECORD_DETAIL> carryDetails = new List<T_PR_DRUG_CARRY_RECORD_DETAIL>();
                List<T_PR_DRUG_CARRY_SAFE_CONFIRM> carryConfirms = new List<T_PR_DRUG_CARRY_SAFE_CONFIRM>();
                if (entity.PUBLISH != null && entity.PUBLISH.Equals("SaveAndNotify"))
                {
                    entity.STATUS = PFStandardStatus.Archived;
                    carry = new T_PR_DRUG_CARRY_RECORD();
                    carry.ORG_ID = entity.ORG_ID;
                    carry.CODE = entity.CODE;
                    carry.OUTBOUND_RECORD_ID = entity.ID;
                    carry.STATUS = PFStandardStatus.Draft;
                    if (details != null && details.Any())
                    {
                        details.ForEach(t =>
                        {
                            T_PR_DRUG_CARRY_RECORD_DETAIL detail = new T_PR_DRUG_CARRY_RECORD_DETAIL();
                            detail.ORG_ID = entity.ORG_ID;
                            detail.DRUG_SET_ID = t.DRUG_SET_ID;
                            detail.TYPE_ID = t.TYPE_ID;
                            detail.SPECIFY_ID = t.SPECIFY_ID;
                            detail.UNIT = t.UNIT;
                            detail.CARRY_RECORD_ID = carry.ID;
                            detail.QTY = t.QTY;
                            carryDetails.Add(detail);
                        });
                    }
                    var drugTypeIds = details.Select(t => t.TYPE_ID).Distinct().ToList();
                    if (drugTypeIds != null && drugTypeIds.Any())
                    {
                        var drugTypes = this.GetEntities<T_PR_DRUG_TYPE>(t => drugTypeIds.Contains(t.ID), new BaseFilter(entity.ORG_ID), "Nav_Confirms").ToList();
                        foreach (var id in drugTypeIds)
                        {
                            var drugTypeFirst = drugTypes.FirstOrDefault(m => m.ID == id.Value);
                            if (drugTypeFirst != null && drugTypeFirst.Nav_Confirms != null && drugTypeFirst.Nav_Confirms.Any())
                            {
                                drugTypeFirst.Nav_Confirms.ForEach(t =>
                                {
                                    T_PR_DRUG_CARRY_SAFE_CONFIRM confirm = new T_PR_DRUG_CARRY_SAFE_CONFIRM();
                                    confirm.ORG_ID = t.ORG_ID;
                                    confirm.TYPE_ID = id;
                                    confirm.NAME = t.NAME;
                                    confirm.IS_CONFIRM = false;
                                    confirm.CARRY_RECORD_ID = carry.ID;
                                    confirm.ROW_NO = t.ROW_NO;
                                    carryConfirms.Add(confirm);
                                });
                            }
                        }
                    }
                    notice = NotificationTaskService.InsertUserNoticeTaskModel("药品（剂）搬运记录表", carry.ID, entity.ORG_ID, user.ID, user.NAME, DateTime.Now,
                                DateTime.Now.AddHours(24), (int)FMNoticeTypeEnum.消息, "PR048");
                }
                UnifiedCommit(() =>
                {
                    if (entity != null)
                        this.UpdateEntityNoCommit(entity);
                    if (details != null && details.Any())
                        this.BantchSaveEntityNoCommit(details);
                    if (carry != null)
                        this.UpdateEntityNoCommit(carry);
                    if (carryDetails != null && carryDetails.Any())
                        this.BantchSaveEntityNoCommit(carryDetails);
                    if (carryConfirms != null && carryConfirms.Any())
                        this.BantchSaveEntityNoCommit(carryConfirms);
                    if (notice != null)
                        this.UpdateEntityNoCommit(notice);
                });
                return true;
            });
        }

        /// <summary>
        /// 新增/编辑
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        [HttpPost, Route("FullUpdateNew")]
        public JsonActionResult<bool> FullUpdateNew([FromBody] T_PR_DRUG_OUTBOUND_RECORD entity)
        {
            return SafeExecute(() =>
            {
                var outUsers = new List<T_PR_DRUG_OUTBOUND_RECORD_DETAIL_USER>();
                var outAccepts = new List<T_PR_DRUG_OUTBOUND_RECORD_DETAIL_ACCEPT>();
                var userIds = new List<Guid>();
                var userNames = new List<string>();
                var userInfos = this.GetEntities<T_FM_USER>(t => t.ENABLE_STATUS == 0, new BaseFilter(entity.ORG_ID), "Nav_Department").ToList();
                if (string.IsNullOrEmpty(entity.CODE))
                    entity.CODE = DateTime.Now.Year.ToString().PadLeft(4, '0') + DateTime.Now.Month.ToString().PadLeft(2, '0') + DateTime.Now.Day.ToString().PadLeft(2, '0') + new Random().Next(9999).ToString().PadLeft(4, '0');
                entity.TIME = DateTime.Now;
                entity.STATUS = PFStandardStatus.Draft;
                var loginUserId = APT.Infrastructure.Api.AppContext.CurrentSession.UserID;
                if (entity.TaskID != Guid.Empty)
                {
                    var currTask = GetEntity<T_FM_NOTIFICATION_TASK>(t => t.ID == entity.TaskID);
                    if (currTask != null)
                    {
                        loginUserId = currTask.USER_ID;
                    }
                }
                entity.USER_ID = loginUserId;
                //var user = this.GetEntity<T_FM_USER>(t => t.ID == loginUserId.Value && t.ENABLE_STATUS == 0);
                entity.DEPARTMENT_ID = this.GetEntity<T_FM_USER>(t => t.ENABLE_STATUS == 0 && t.ID == (Guid)loginUserId)?.DEPARTMENT_ID;
                var details = entity.Nav_Details;
                entity.Nav_Details = null;
                if (details != null && details.Any())
                {
                    details.ForEach(t =>
                    {
                        t.ORG_ID = entity.ORG_ID; t.OUTBOUND_RECORD_ID = entity.ID; t.CARRY_TIME = DateTime.Now;
                        var departName = "";
                        if (t.Nav_Users != null && t.Nav_Users.Any())
                        {
                            var i = 0;
                            t.Nav_Users.ForEach(t1 =>
                            {
                                if (t1.USER_ID == loginUserId && entity.PUBLISH != null && entity.PUBLISH.Equals("SaveAndNotify"))
                                {
                                    t1.DEAL_STATUS = FOUserShiftStatusEnum.已处理;
                                }
                                t1.OUTBOUND_RECORD_DETAIL_ID = t.ID;
                                t1.ORG_ID = t.ORG_ID;
                                t1.ROW_NO = i++;
                                outUsers.Add(t1);
                                var departUser = userInfos.FirstOrDefault(m => m.ID == t1.USER_ID);
                                departName = departUser?.Nav_Department?.NAME + " " + departName;
                                if (!t1.IS_DELETED && t1.USER_ID != null)
                                    userIds.Add(t1.USER_ID.Value);
                            });
                        }
                        t.DEPARTMENT = departName;
                        if (t.Nav_Accepts != null && t.Nav_Accepts.Any())
                        {
                            var i = 0;
                            t.Nav_Accepts.ForEach(t2 =>
                            {
                                t2.OUTBOUND_RECORD_DETAIL_ID = t.ID;
                                t2.ORG_ID = t.ORG_ID;
                                t2.ROW_NO = i++;
                                outAccepts.Add(t2);
                                var departUser = userInfos.FirstOrDefault(m => m.ID == t2.USER_ID);
                                if (!t2.IS_DELETED && t2.USER_ID != null)
                                    userIds.Add(t2.USER_ID.Value);
                            });
                        }
                    });
                }
                else
                    throw new Exception("药品明细不能为空");
                var notices = new List<T_FM_NOTIFICATION_TASK>();
                var carry = new List<T_PR_DRUG_CARRY_RECORD>();
                var carryDetails = new List<T_PR_DRUG_CARRY_RECORD_DETAIL>();
                var carryConfirms = new List<T_PR_DRUG_CARRY_SAFE_CONFIRM>();
                var carryUsers = new List<T_PR_DRUG_CARRY_RECORD_DETAIL_USER>();
                var carryAccepts = new List<T_PR_DRUG_CARRY_RECORD_DETAIL_ACCEPT>();
                if (entity.PUBLISH != null && entity.PUBLISH.Equals("SaveAndNotify"))
                {
                    entity.STATUS = PFStandardStatus.Archived;
                    var groupDetails = new List<DrugCarryRecordModel>();
                    foreach (var item in details)
                    {
                        DrugCarryRecordModel model = new DrugCarryRecordModel();
                        model.SPECIFY_ID = item.SPECIFY_ID;
                        model.DRUG_SET_ID = item.DRUG_SET_ID;
                        model.UNIT = item.UNIT;
                        model.TYPE_ID = item.TYPE_ID;
                        model.QTY = item.QTY;
                        model.DEPARTMENT_NAME = item.DEPARTMENT;
                        if (item.Nav_Users != null && item.Nav_Users.Any())
                        {
                            var userId = item.Nav_Users.FirstOrDefault()?.USER_ID;
                            model.USER_ID = userId;
                        }
                        else
                        {
                            throw new Exception("搬运人员不能为空");
                        }
                        if (item.Nav_Accepts != null && item.Nav_Accepts.Any())
                        {
                        }
                        else
                        {
                            throw new Exception("使用人员不能为空");
                        }
                        groupDetails.Add(model);
                    }
                    var drugTypeIds = groupDetails.Select(t => t.TYPE_ID).Distinct().ToList();
                    var groupDetailTemps = groupDetails.GroupBy(t =>new { t.TYPE_ID,t.USER_ID}).Distinct().ToList();
                    if (groupDetailTemps != null && groupDetailTemps.Any())
                    {
                        var drugTypes = this.GetEntities<T_PR_DRUG_TYPE>(t => drugTypeIds.Contains(t.ID), new BaseFilter(entity.ORG_ID), "Nav_Confirms").ToList();
                        foreach (var id in groupDetailTemps)
                        {
                            var userTempIDs = new List<Guid?>();
                            var carryTemp = new T_PR_DRUG_CARRY_RECORD();
                            //按药剂类型不同，生成搬运记录
                            carryTemp.ORG_ID = entity.ORG_ID;
                            carryTemp.CODE = entity.CODE;
                            carryTemp.OUTBOUND_RECORD_ID = entity.ID;
                            carryTemp.STATUS = PFStandardStatus.Draft;
                            carryTemp.TYPE_ID = id.Key.TYPE_ID;
                            carry.Add(carryTemp);
                            var detailTemps = details.Where(t => t.TYPE_ID == id.Key.TYPE_ID && t.Nav_Users!=null && t.Nav_Users.FirstOrDefault()?.USER_ID == id.Key.USER_ID).ToList();
                            if (detailTemps != null && detailTemps.Any())
                            {
                                detailTemps.ForEach(t =>
                                {
                                    T_PR_DRUG_CARRY_RECORD_DETAIL detail = new T_PR_DRUG_CARRY_RECORD_DETAIL();
                                    detail.ORG_ID = entity.ORG_ID;
                                    detail.DRUG_SET_ID = t.DRUG_SET_ID;
                                    detail.TYPE_ID = t.TYPE_ID;
                                    detail.SPECIFY_ID = t.SPECIFY_ID;
                                    detail.UNIT = t.UNIT;
                                    detail.CARRY_RECORD_ID = carryTemp.ID;
                                    detail.QTY = t.QTY;
                                    detail.CARRY_TIME = t.CARRY_TIME;
                                    detail.PLACE_ID = t.PLACE_ID;
                                    detail.DEPARTMENT = t.DEPARTMENT;
                                    carryDetails.Add(detail);
                                    if (t.Nav_Users != null && t.Nav_Users.Any())
                                    {
                                        var i = 0;
                                        t.Nav_Users.ForEach(t1 =>
                                        {
                                            if (t1.IS_DELETED == false)
                                            {
                                                var userName = userInfos.FirstOrDefault(m => m.ID == t1.USER_ID)?.NAME;
                                                var notice = NotificationTaskService.InsertUserNoticeTaskModel("药品（剂）出库记录表-确认", entity.ID, entity.ORG_ID, (Guid)t1.USER_ID, userName, DateTime.Now,
                                                  DateTime.Now.AddHours(24), (int)FMNoticeTypeEnum.消息, "PR046_ShowPrint");
                                                if (t1.USER_ID == loginUserId)
                                                {
                                                    notice.NOTICE_STATUS = (int)FMNoticeStatusEnum.正常已办;
                                                }
                                                notices.Add(notice);
                                                T_PR_DRUG_CARRY_RECORD_DETAIL_USER user = new T_PR_DRUG_CARRY_RECORD_DETAIL_USER();
                                                user.ORG_ID = entity.ORG_ID;
                                                user.USER_ID = t1.USER_ID;
                                                user.DEAL_STATUS = t1.DEAL_STATUS;
                                                user.CARRY_RECORD_DETAIL_ID = detail.ID;
                                                user.ROW_NO = i++;
                                                carryUsers.Add(user);
                                                userTempIDs.Add(t1.USER_ID);
                                            }
                                        });
                                    }
                                    if (t.Nav_Accepts != null && t.Nav_Accepts.Any())
                                    {
                                        var i = 0;
                                        t.Nav_Accepts.ForEach(t1 =>
                                        {
                                            if (t1.IS_DELETED == false)
                                            {
                                                var userName = userInfos.FirstOrDefault(m => m.ID == t1.USER_ID)?.NAME;
                                                var notice = NotificationTaskService.InsertUserNoticeTaskModel("药品（剂）出库记录表-确认", entity.ID, entity.ORG_ID, (Guid)t1.USER_ID, userName, DateTime.Now,
                                                  DateTime.Now.AddHours(24), (int)FMNoticeTypeEnum.消息, "PR046_ShowPrint");
                                                if (t1.USER_ID == loginUserId)
                                                {
                                                    notice.NOTICE_STATUS = (int)FMNoticeStatusEnum.正常已办;
                                                }
                                                notices.Add(notice);
                                                T_PR_DRUG_CARRY_RECORD_DETAIL_ACCEPT user = new T_PR_DRUG_CARRY_RECORD_DETAIL_ACCEPT();
                                                user.ORG_ID = entity.ORG_ID;
                                                user.USER_ID = t1.USER_ID;
                                                user.ROW_NO = i++;
                                                user.CARRY_RECORD_DETAIL_ID = detail.ID;
                                                carryAccepts.Add(user);
                                            }
                                        });
                                    }
                                });
                            }
                            var drugTypeFirst = drugTypes.FirstOrDefault(m => m.ID == id.Key.TYPE_ID);
                            if (drugTypeFirst != null && drugTypeFirst.Nav_Confirms != null && drugTypeFirst.Nav_Confirms.Any())
                            {
                                drugTypeFirst.Nav_Confirms.ForEach(t =>
                                {
                                    T_PR_DRUG_CARRY_SAFE_CONFIRM confirm = new T_PR_DRUG_CARRY_SAFE_CONFIRM();
                                    confirm.ORG_ID = t.ORG_ID;
                                    confirm.TYPE_ID = id.Key.TYPE_ID;
                                    confirm.NAME = t.NAME;
                                    confirm.IS_CONFIRM = false;
                                    confirm.CARRY_RECORD_ID = carryTemp.ID;
                                    confirm.ROW_NO = t.ROW_NO;
                                    carryConfirms.Add(confirm);
                                });
                            }
                            if (id.Key.USER_ID != null)
                            {
                                //var userId = userTempIDs.FirstOrDefault().Value;
                                var userName = userInfos.FirstOrDefault(m => m.ID == id.Key.USER_ID)?.NAME;
                                notices.Add(NotificationTaskService.InsertUserNoticeTaskModel("药品（剂）搬运记录表", carryTemp.ID, entity.ORG_ID, (Guid)id.Key.USER_ID, userName, DateTime.Now,
                                            DateTime.Now.AddHours(24), (int)FMNoticeTypeEnum.消息, "PR048"));
                            }
                        }
                    }
                    
                    //var userIdsTemp = userIds.Where(t => t != loginUserId).Distinct().ToList();
                    //var userTemps = userInfos.Where(t => userIdsTemp.Contains(t.ID)).ToList();
                    //userTemps.ForEach(t => userNames.Add(t.NAME));
                    //notices.AddRange(NotificationTaskService.InsertUserNoticeTaskModels("药品（剂）出库记录表-确认", entity.ID, entity.ORG_ID, userIdsTemp, userNames, DateTime.Now,
                    //                   DateTime.Now.AddHours(24), (int)FMNoticeTypeEnum.消息, "PR046_ShowPrint"));
                }
                details.ForEach(t => { t.Nav_Users = null; t.Nav_Accepts = null; });
                UnifiedCommit(() =>
                {
                    if (entity != null)
                        this.UpdateEntityNoCommit(entity);
                    if (details != null && details.Any())
                        this.BantchSaveEntityNoCommit(details);
                    if (outUsers != null && outUsers.Any())
                        this.BantchSaveEntityNoCommit(outUsers);
                    if (outAccepts != null && outAccepts.Any())
                        this.BantchSaveEntityNoCommit(outAccepts);
                    if (carry != null && carry.Any())
                        this.BantchSaveEntityNoCommit(carry);
                    if (carryDetails != null && carryDetails.Any())
                        this.BantchSaveEntityNoCommit(carryDetails);
                    if (carryConfirms != null && carryConfirms.Any())
                        this.BantchSaveEntityNoCommit(carryConfirms);
                    if (carryUsers != null && carryUsers.Any())
                        this.BantchSaveEntityNoCommit(carryUsers);
                    if (carryAccepts != null && carryAccepts.Any())
                        this.BantchSaveEntityNoCommit(carryAccepts);
                    if (notices != null && notices.Any())
                        this.BantchSaveEntityNoCommit(notices);
                });
                return true;
            });
        }

        /// <summary>
        /// 确认
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        [HttpPost, Route("IdentityUpdate")]
        public JsonActionResult<bool> IdentityUpdate([FromBody] T_PR_DRUG_OUTBOUND_RECORD entity)
        {
            return SafeExecute(() => {
                var carryUsers = new List<T_PR_DRUG_OUTBOUND_RECORD_DETAIL_USER>();
                var acceptUsers = new List<T_PR_DRUG_OUTBOUND_RECORD_DETAIL_ACCEPT>();
                var monitor = this.GetEntity<T_PR_DRUG_OUTBOUND_RECORD>(entity.ID, "Nav_Details", "Nav_Details.Nav_Users", "Nav_Details.Nav_Accepts");
                var userId = APT.Infrastructure.Api.AppContext.CurrentSession.UserID;
                if (entity.TaskID != Guid.Empty)
                {
                    var currTask = GetEntity<T_FM_NOTIFICATION_TASK>(t => t.ID == entity.TaskID);
                    if (currTask != null)
                    {
                        userId = currTask.USER_ID;
                    }
                }
                if (monitor != null && monitor.Nav_Details != null && monitor.Nav_Details.Any())
                {
                    foreach (var item in monitor.Nav_Details)
                    {
                        if (item.Nav_Users != null && item.Nav_Users.Any())
                        {
                            item.Nav_Users.ForEach(t =>
                            {
                                if (t.USER_ID == userId)
                                {
                                    t.DEAL_STATUS = FOUserShiftStatusEnum.已处理;
                                    carryUsers.Add(t);
                                }
                            });
                        }

                        if (item.Nav_Accepts != null && item.Nav_Accepts.Any())
                        {
                            item.Nav_Accepts.ForEach(t =>
                            {
                                if (t.USER_ID == userId)
                                {
                                    t.DEAL_STATUS = FOUserShiftStatusEnum.已处理;
                                    acceptUsers.Add(t);
                                }
                            });
                        }
                    }
                }
                T_FM_NOTIFICATION_TASK task = null;
                if (entity.TaskID != Guid.Empty)
                {
                    task = NotificationTaskService.GetTaskFinishModel(entity.TaskID);
                    task.SOURCE_FORMCODE = "PR046_SHOWPRINT";
                }
                UnifiedCommit(() =>
                {
                    if (carryUsers != null && carryUsers.Any())
                        this.BantchSaveEntityNoCommit(carryUsers);
                    if (acceptUsers != null && acceptUsers.Any())
                        this.BantchSaveEntityNoCommit(acceptUsers);
                    if (task != null)
                        this.UpdateEntityNoCommit(task);
                });
                return true;
            });
        }
    }
}
