using Microsoft.AspNetCore.Mvc;
using System;
using WCS.BLL.DbModels;
using WCS.BLL.Manager;
using WCS.BLL.Services.IService;
using WCS.BLL.Services.Service;
using WCS.DAL.Db;
using WCS.DAL.DbModels;
using WCS.Model;
using WCS.Model.ApiModel.LocationInfo;
using WCS.Model.ApiModel.MatBaseInfo;
using WCS.Model.ApiModel.MatDetailCurrentInfo;
using WCS.Model.ApiModel.MatDetailHistoryInfo;
using WCS.Model.ApiModel.PDAProductionLineCallIn;
using WCS.Model.ApiModel.PDAProductionLineCallOut;
using WCS.Model.ApiModel.PDAShelfLocationBindUnbind;
using WCS.Model.ApiModel.Stocktaking;
using WCS.Model.ApiModel.StoreInfo;

namespace WCS.WebApi.Controllers
{
    /// <summary>
    /// PDA产线呼叫功能
    /// </summary>
    [ApiController]
    [Route("[controller]")]
    public class PDAProductionLineCallOutController : ControllerBase
    {

        public PDAProductionLineCallOutController(IStockTakingService stockTakingService)
        {

        }

        /// <summary>
        /// 获取当前货架、当前货架的工位、当前工位可以作为起点可以到的目标区域
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("getShelfInfoForCallOut")]
        [HttpPost(Name = "getShelfInfoForCallOut")]
        public async Task<ResponseCommon> getShelfInfoForCallOut(GetShelfInfoForCallOutRequest request)
        {
            try
            {
                //校验参数
                if (string.IsNullOrEmpty(request.ShelfCode))
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = "参数错误，请重新扫描货架码！",
                        Data = null,
                    };
                }
                //通过货架编码获取货架
                var shelfInfo = await DbHelp.db.Queryable<ShelfInfo>()
                                               .Where(t => t.ShelfCode == request.ShelfCode)
                                               .Where(t => t.IsEnable)
                                               .FirstAsync();
                if (shelfInfo == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"货架{request.ShelfCode}不存在或已被禁用！",
                        Data = null,
                    };
                }
                //货架不处于静止状态
                if (shelfInfo.TransStatus == TransStatusEnum.运输中)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"货架{request.ShelfCode}处于运输中！",
                        Data = null,
                    };
                }
                //货架未绑定位置信息
                if (string.IsNullOrEmpty(shelfInfo.CurrentLocaiotnCode) || shelfInfo.CurrentLocationId == 0)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"货架{request.ShelfCode}未绑定位置信息！",
                        Data = null,
                    };
                }
                //位置校验
                var locationInfo = await DbHelp.db.Queryable<LocationInfo>()
                                               .Where(t => t.Id == shelfInfo.CurrentLocationId)
                                               .Where(t => t.IsEnable)
                                               .FirstAsync();
                if (locationInfo == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"工位{shelfInfo.CurrentLocaiotnCode}不存在或已被禁用！",
                        Data = null,
                    };
                }
                //获取工位作为起点 可以放置的目标区域
                var locationAreas = await DbHelp.db.Queryable<LocationAreaInfo>()
                                                   .WhereIF(locationInfo.AllowDestinationLocationArea != null && locationInfo.AllowDestinationLocationArea.Count > 0, t => locationInfo.AllowDestinationLocationArea.Contains(t.Id))
                                                   .Select(t => new LocationAreaInfoModel()
                                                   {
                                                       Id = t.Id,
                                                       LocationAreaName = t.LocationAreaName,
                                                   })
                                                   .ToListAsync();
                locationAreas = locationAreas.Append(new LocationAreaInfoModel() { Id = 0, LocationAreaName = "请选择" })
                    .OrderBy(t => t.Id).ToList();

                return new ResponseCommon()
                {
                    Code = 200,
                    Message = "success",
                    Data = new GetShelfInfoForCallOutResponseData()
                    {
                        ShelfId = shelfInfo.Id,
                        ShelfCode = shelfInfo.ShelfCode,
                        LocationId = locationInfo.Id,
                        LocationCode = locationInfo.LocationCode,
                        LocationAreas = locationAreas
                    }
                };
            }
            catch (Exception ex)
            {
                return new ResponseCommon()
                {
                    Code = 201,
                    Message = ex.Message,
                    Data = null,
                };
            }
        }

        /// <summary>
        /// 货架送回修改数量
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("updateMatDetailCurrentInfoForCallOut")]
        [HttpPost(Name = "updateMatDetailCurrentInfoForCallOut")]
        public async Task<ResponseCommon<object>> updateMatDetailCurrentInfoForCallOut(UpdateMatDetailCurrentInForCallOutRequest request)
        {
            try
            {
                var matDetailCurrentInfo = await DbHelp.db.Queryable<MatDetailCurrentInfo>()     //.Where(t => t.MatDetailCurrentCode == request.MatDetailCurrentInfo.MatDetailCurrentCode)
                                                          .Where(t => t.Id == request.MatDetailCurrentInfoId)
                                                          .FirstAsync();
                if (matDetailCurrentInfo == null)
                {
                    return new ResponseCommon<Object>
                    {
                        Code = 205,
                        Message = $"更新库存信息失败：此条数据不存在，请确认！",
                        Data = null
                    };
                }
                DbHelp.db.BeginTran();
                //新增数据修改记录表
                var historyInfo = new MatDetailHistoryInfo()
                {
                    ShlefId = matDetailCurrentInfo.ShelfId,
                    ShelfType = matDetailCurrentInfo.ShelfType,
                    ShelfCode = matDetailCurrentInfo.ShelfCode,

                    MatCode = matDetailCurrentInfo.MatCode,
                    MatName = matDetailCurrentInfo.MatName,
                    MatBatch = matDetailCurrentInfo.MatBatch,
                    MatSpec = matDetailCurrentInfo.MatSpec,
                    MatCustomer = matDetailCurrentInfo?.MatCustomer,
                    MatSupplier = matDetailCurrentInfo?.MatSupplier,

                    BeforeQty = matDetailCurrentInfo.MatQty,
                    AfterQty = request.MatQty,

                    ModifyTime = DateTime.Now,
                    ModifyUser = request.UserName,
                    RecordType = RecordTypeEnum.修改,
                    FunctionType = FunctionTypeEnum.PDA货架送回,
                };
                await DbHelp.db.Insertable(historyInfo).ExecuteCommandAsync();
                //更新货架存量数据
                matDetailCurrentInfo.MatQty = request.MatQty;
                matDetailCurrentInfo.ModifyUser = request.UserName;
                matDetailCurrentInfo.ModifyTime = DateTime.Now;
                var rowNum = await DbHelp.db.Updateable(matDetailCurrentInfo).ExecuteCommandAsync();
                if (rowNum == 0)
                {
                    DbHelp.db.RollbackTran();
                    return new ResponseCommon<Object>
                    {
                        Code = 201,
                        Message = $"更新货架存量信息失败：请重试！",
                        Data = null
                    };
                }
                else
                {
                    DbHelp.db.CommitTran();
                    DataProcessManager.UpdateShelfStatus();
                    return new ResponseCommon<Object>
                    {
                        Code = 200,
                        Message = $"更新货架存量信息成功！",
                        Data = null
                    };
                }
            }
            catch (Exception ex)
            {
                DbHelp.db.RollbackTran();
                var response = new ResponseCommon<Object>
                {
                    Code = 300,
                    Message = $"操作失败:{ex.Message}",
                    Data = null
                };
                return response;
            }
        }

        /// <summary>
        /// 货架送回 通过 货架ID 目标区域 是否为空货架等参数 将货架送回
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("callOut")]
        [HttpPost(Name = "callOut")]
        public async Task<ResponseCommon> callOut(CallOutRequest request)
        {
            try
            {
                #region 校验位置
                if (request.LocationId == 0)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"送回失败:请重新扫描货架码!",
                        Data = null,
                    };
                }
                //获取当前工位-起点工位
                var startLocation = await DbHelp.db.Queryable<LocationInfo>()
                                                  .Where(t => t.Id == request.LocationId)
                                                  .FirstAsync();
                if (startLocation == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"当前工位{request.LocationCode}不存在!",
                        Data = null,
                    };
                }

                if (startLocation.IsEnable == false)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"当前工位{startLocation.LocationCode}已被禁用!",
                        Data = null,
                    };
                }


                #endregion

                #region 校验货架
                var shelfInfo = await DbHelp.db.Queryable<ShelfInfo>()
                         .Where(t => t.Id == request.ShelfId)
                         .Where(t => t.IsEnable)
                         .FirstAsync();
                if (shelfInfo == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 301,
                        Message = $"当前货架{request.ShelfCode}不存在或已被禁用!",
                        Data = null,
                    };
                }

                if (shelfInfo.TransStatus == TransStatusEnum.运输中)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"当前货架{shelfInfo.ShelfCode}已有任务在运输中!",
                        Data = null,
                    };
                }

                if (shelfInfo.CurrentLocationId != startLocation.Id)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"当前货架{shelfInfo.ShelfCode}已不在工位{startLocation.LocationCode}上!",
                        Data = null,
                    };
                }
                #endregion

                #region 操作库存信息
                if (request.ShelfTypeStr == "空货架" || request.ShelfTypeStr == "empty")
                {
                    var matCurrentInfos = await DbHelp.db.Queryable<MatDetailCurrentInfo>()
                                                         .Where(t => t.ShelfId == shelfInfo.Id)
                                                         .ToListAsync();
                    //库存更新记录
                    //执行删除
                    try
                    {
                        DbHelp.db.BeginTran();
                        //新增数据删除记录
                        foreach (var matDetailCurrentInfo in matCurrentInfos)
                        {
                            var historyInfo = new MatDetailHistoryInfo()
                            {
                                ShlefId = matDetailCurrentInfo.ShelfId,
                                ShelfType = matDetailCurrentInfo.ShelfType,
                                ShelfCode = matDetailCurrentInfo.ShelfCode,

                                MatCode = matDetailCurrentInfo.MatCode,
                                MatName = matDetailCurrentInfo.MatName,
                                MatBatch = matDetailCurrentInfo.MatBatch,
                                MatSpec = matDetailCurrentInfo.MatSpec,
                                MatCustomer = matDetailCurrentInfo?.MatCustomer,
                                MatSupplier = matDetailCurrentInfo?.MatSupplier,

                                BeforeQty = matDetailCurrentInfo.MatQty,
                                AfterQty = 0,//删除数据 为0

                                ModifyTime = DateTime.Now,
                                ModifyUser = request.UserName,
                                RecordType = RecordTypeEnum.清空,
                                FunctionType = FunctionTypeEnum.PDA货架送回,
                            };
                            await DbHelp.db.Insertable(historyInfo).ExecuteCommandAsync();
                        }
                        DbHelp.db.Deleteable(matCurrentInfos).ExecuteCommand();
                        DbHelp.db.CommitTran();
                        DataProcessManager.UpdateShelfStatus();
                    }
                    catch (Exception ex)
                    {
                        DbHelp.db.RollbackTran();
                        return new ResponseCommon
                        {
                            Code = 300,
                            Message = $"操作失败:{ex.Message}",
                            Data = null
                        };
                    }
                }
                //如果不是非空货架 那么就清除数量为0的库存
                else
                {
                    var matCurrentInfos = await DbHelp.db.Queryable<MatDetailCurrentInfo>()
                                                             .Where(t => t.ShelfId == shelfInfo.Id)
                                                             .Where(t => t.MatQty == 0)
                                                             .ToListAsync();
                    //库存更新记录
                    //全部删除 删除数量为0的
                    DbHelp.db.Deleteable(matCurrentInfos).ExecuteCommand();
                    DataProcessManager.UpdateShelfStatus();
                }
                #endregion

                //根据选择的区域信息获取终点
                var endLocation = await DbHelp.db.Queryable<LocationInfo>()
                                                 .LeftJoin<ShelfInfo>((li, si) => (li.Id == si.CurrentLocationId && si.TransStatus == TransStatusEnum.静止) || (li.Id == si.DestinationLocationId && si.TransStatus == TransStatusEnum.运输中))
                                                 .Where((li, si) => li.LocationAreaId == request.DestinationLocationAreaId)
                                                 .Where((li, si) => li.IsEnable == true)
                                                 .Where((li, si) => li.Id != shelfInfo.CurrentLocationId)
                                                 .Where((li, si) => si.Id == null)
                                                 .Select((li, si) => li)
                                                 .FirstAsync();
                if (endLocation == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"目标库区[{request.DestinationLocationAreaName}]不存在空闲位置！",
                        Data = null,
                    };
                }

                #region AGV接口
                //TO DO 调用AGV接口开始呼叫 呼叫成功更新运输状态和目标库位
                var response = AGVManager.GenAgvSchedulingTask(startLocation, endLocation, shelfInfo.ShelfCode, request.UserName);
                if (response.code == "0" && response.message == "成功")
                {
                    //更新货架位置信息
                    shelfInfo.TransStatus = TransStatusEnum.运输中;
                    shelfInfo.CurrentTaskCode = response.data;
                    shelfInfo.DestinationLocationId = endLocation.Id;
                    shelfInfo.DestinationLocaiotnCode = endLocation.LocationCode;
                    DbHelp.db.Updateable(shelfInfo).ExecuteCommand();

                    return new ResponseCommon()
                    {
                        Code = 200,
                        Message = "success",
                        Data = null,
                    };
                }
                else if (response.code == "-999")
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"{response.message}\r\n请重试或等待上一个任务完成",
                        Data = null,
                    };
                }
                else
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"海康RCS返回：{response.message}",
                        Data = null,
                    };
                }
                #endregion
            }
            catch (Exception ex)
            {
                return new ResponseCommon()
                {
                    Code = 201,
                    Message = ex.Message,
                    Data = null,
                };
            }
        }
    }
}
