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.MatBaseInfo;
using WCS.Model.ApiModel.MatDetailCurrentInfo;
using WCS.Model.ApiModel.PDAProductionLineCallIn;
using WCS.Model.ApiModel.PDAShelfLocationBindUnbind;
using WCS.Model.ApiModel.Stocktaking;

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

        public PDAProductionLineCallInController(IStockTakingService stockTakingService)
        {

        }

        /// <summary>
        /// 扫描工位码  获取工位信息 返回工位是否可以呼叫货架等信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("getLocationInfoForCallIn")]
        [HttpPost(Name = "getLocationInfoForCallIn")]
        public async Task<ResponseCommon> getLocationInfoForCallIn(GetLocationInfoForCallInRequest request)
        {
            try
            {
                #region 参数校验
                if (string.IsNullOrEmpty(request.LocationCode))
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"参数错误:请重新扫描工位码!",
                        Data = null,
                    };
                }
                #endregion
                //获取位置信息
                var locationInfo = await DbHelp.db.Queryable<LocationInfo>()
                                            .Where(t => t.LocationCode == request.LocationCode)
                                            .FirstAsync();
                if (locationInfo == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"获取失败:工位{request.LocationCode}不存在!",
                        Data = null,
                    };
                }

                if (locationInfo.IsEnable == false)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"获取失败:工位{locationInfo.LocationCode}已被禁用!",
                        Data = null,
                    };
                }

                var shelfInfo = await DbHelp.db.Queryable<ShelfInfo>()
                                         .Where(t => t.CurrentLocationId == locationInfo.Id)
                                         .FirstAsync();

                return new ResponseCommon()
                {
                    Code = 200,
                    Message = $"success",
                    Data = new GetLocationInfoForCallInResponseData()
                    {
                        LocationId = locationInfo.Id,
                        LocationCode = locationInfo.LocationCode,
                        ShelfTransStatusStr = shelfInfo?.TransStatus.ToString(),
                        ShelfCode = shelfInfo?.ShelfCode,
                    },
                };
            }
            catch (Exception ex)
            {
                return new ResponseCommon()
                {
                    Code = 201,
                    Message = ex.Message,
                    Data = null,
                };
            }
        }

        /// <summary>
        /// 通过工位码、模糊搜索条件  返回库存存量数据（带货架信息的）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("getMatDetailCurrentInfosForCallIn")]
        [HttpPost(Name = "getMatDetailCurrentInfosForCallIn")]
        public async Task<ResponseCommon> getMatDetailCurrentInfosForCallIn(GetMatDetailCurrentInfosForCallInRequest request)
        {
            try
            {
                #region 校验位置是否可以呼叫货架
                if (request.LocationId == 0)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"参数错误,请重新扫描工位码!",
                        Data = null,
                    };
                }
                //获取位置信息
                var locationInfo = await DbHelp.db.Queryable<LocationInfo>()
                                            .Where(t => t.Id == request.LocationId)
                                            .FirstAsync();
                if (locationInfo == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"工位{request.LocationCode}不存在!",
                        Data = null,
                    };
                }
                if (locationInfo.IsEnable == false)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"工位{locationInfo.LocationCode}已被禁用!",
                        Data = null,
                    };
                }

                var shelfInfo = await DbHelp.db.Queryable<ShelfInfo>()
                                         .Where(t => t.CurrentLocationId == locationInfo.Id || t.DestinationLocationId == locationInfo.Id)
                                         .FirstAsync();
                if (shelfInfo != null)
                {
                    if (shelfInfo.TransStatus == TransStatusEnum.运输中)
                    {
                        shelfInfo.ShelfCode = shelfInfo.ShelfCode + "(运输中)";
                    }
                    return new ResponseCommon()
                    {
                        Code = 301,
                        Message = $"当前工位[{locationInfo.LocationCode}]\r\n已被货架[{shelfInfo.ShelfCode}]占用\r\n无法通过此功能进行呼叫!",
                        Data = null,
                    };
                }
                #endregion

                #region 查询货架当前存量
                var recordsQueryable = DbHelp.db.Queryable<MatDetailCurrentInfo>()
                                                .LeftJoin<ShelfInfo>((mci, si) => mci.ShelfId == si.Id)
                                                //货架状态是静止的 代表这个货架没有被呼叫走哦
                                                .LeftJoin<LocationInfo>((mci, si, li) => (si.TransStatus == TransStatusEnum.静止 && si.CurrentLocationId == li.Id))
                                                .WhereIF(!string.IsNullOrEmpty(request.MatCodeCondition), (mci, si, li) => mci.MatCode.Contains(request.MatCodeCondition) || mci.MatName.Contains(request.MatCodeCondition))
                                                .OrderBy((mci, si, li) => mci.ShelfCode)//排序规则
                                                .OrderBy((mci, si, li) => mci.MatCode)
                                                .OrderBy((mci, si, li) => mci.MatBatch)
                                                .Select((mci, si, li) => new MatDetailCurrentInfoModel()
                                                {
                                                    Id = mci.Id,
                                                    ShelfId = mci.ShelfId,
                                                    ShelfCode = mci.ShelfCode,
                                                    ShelfType = mci.ShelfType,

                                                    LocationArea = li.LocationArea,
                                                    LocationCode = li.LocationCode,

                                                    MatCode = mci.MatCode,
                                                    MatName = mci.MatName,
                                                    MatBatch = mci.MatBatch,
                                                    MatSpec = mci.MatSpec,
                                                    MatUnit = mci.MatUnit,
                                                    MatCustomer = mci.MatCustomer,
                                                    MatQty = mci.MatQty,
                                                    MatSupplier = mci.MatSupplier,

                                                    StationCode = mci.StationCode,
                                                    ModifyUser = mci.ModifyUser,
                                                    ModifyTime = mci.ModifyTime
                                                });

                //分页
                var totalCount = await recordsQueryable.CountAsync();
                var records = await recordsQueryable

                                    .Skip(0).Take(300)
                                    .ToListAsync();
                return new PageQueryResponse<MatDetailCurrentInfoModel>()
                {
                    Code = 200,
                    Message = $"success",
                    Data = new PageQueryResponseData<MatDetailCurrentInfoModel>()
                    {
                        TotalCount = totalCount,
                        MaxPage = 1,
                        Count = records.Count,
                        Lists = records.ToList()
                    }
                };
                #endregion
            }
            catch (Exception ex)
            {
                return new ResponseCommon()
                {
                    Code = 201,
                    Message = ex.Message,
                    Data = null,
                };
            }
        }

        /// <summary>
        /// 呼叫货架 通过工位ID（终点） 货架ID 等信息呼叫货架
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("callIn")]
        [HttpPost(Name = "callIn")]
        public async Task<ResponseCommon> callIn(CallInRequest request)
        {
            try
            {
                #region 校验位置是否可以呼叫货架
                if (request.LocationId == 0)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"请重新扫描工位码!",
                        Data = null,
                    };
                }
                //获取位置信息
                var endLocation = await DbHelp.db.Queryable<LocationInfo>()
                                            .Where(t => t.Id == request.LocationId)
                                            .FirstAsync();
                if (endLocation == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"当前工位{request.LocationCode}不存在!",
                        Data = null,
                    };
                }
                if (endLocation.IsEnable == false)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"当前工位{endLocation.LocationCode}已被禁用!",
                        Data = null,
                    };
                }

                var shelfInfo = await DbHelp.db.Queryable<ShelfInfo>()
                                         .Where(t => t.CurrentLocationId == endLocation.Id && t.TransStatus == TransStatusEnum.静止)
                                         .FirstAsync();
                if (shelfInfo != null)
                {
                    return new ResponseCommon()
                    {
                        Code = 301,
                        Message = $"当前工位{endLocation.LocationCode}已被货架{shelfInfo.ShelfCode}占用!",
                        Data = null,
                    };
                }

                shelfInfo = await DbHelp.db.Queryable<ShelfInfo>()
                                         .Where(t => t.DestinationLocationId == endLocation.Id && t.TransStatus == TransStatusEnum.运输中)
                                         .FirstAsync();
                if (shelfInfo != null)
                {
                    return new ResponseCommon()
                    {
                        Code = 301,
                        Message = $"当前工位{endLocation.LocationCode}已呼叫货架{shelfInfo.ShelfCode}!\r\n请勿重新呼叫！",
                        Data = null,
                    };
                }
                #endregion

                #region 获取货架是否可以被呼叫
                shelfInfo = await DbHelp.db.Queryable<ShelfInfo>()
                                               .Where(t => t.Id == request.ShelfId)
                                               .Where(t => t.IsEnable)
                                               .FirstAsync();
                if (shelfInfo == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"货架{shelfInfo.ShelfCode}不存在或已被禁用!",
                        Data = null,
                    };
                }
                if (shelfInfo.TransStatus == TransStatusEnum.运输中)
                {
                    if (shelfInfo.DestinationLocationId == request.LocationId)
                    {
                        return new ResponseCommon()
                        {
                            Code = 201,
                            Message = $"呼叫失败:货架{shelfInfo.ShelfCode}已呼叫至当前工位，请等待!",
                            Data = null,
                        };
                    }
                    else
                    {
                        return new ResponseCommon()
                        {
                            Code = 201,
                            Message = $"呼叫失败:货架{shelfInfo.ShelfCode}正在被运输中，请选择其他货架!",
                            Data = null,
                        };
                    }
                }

                //获取起点位置
                if (shelfInfo.CurrentLocationId == 0 || string.IsNullOrEmpty(shelfInfo.CurrentLocaiotnCode))
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"货架{shelfInfo.ShelfCode}未与位置绑定，无法呼叫!",
                        Data = null,
                    };
                }
                var startLocation = await DbHelp.db.Queryable<LocationInfo>()
                                                   .Where(t => t.Id == shelfInfo.CurrentLocationId)
                                                   .FirstAsync();
                if (startLocation == null)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"货架{shelfInfo.ShelfCode}未与位置绑定，无法呼叫!",
                        Data = null,
                    };
                }
                if (startLocation.IsEnable == false)
                {
                    return new ResponseCommon()
                    {
                        Code = 201,
                        Message = $"货架{shelfInfo.ShelfCode}所在位置已被禁用，无法呼叫!",
                        Data = null,
                    };
                }
                #endregion

                #region 调用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,
                };
            }
        }
    }
}
