using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Common;
using Siger.ApiCommon.Filters;
using Siger.Middlelayer.AccRepository.Entities;
using Siger.Middlelayer.AccRepository.Repositories.Interface;
using Siger.Middlelayer.AccRepository.Request;
using Siger.Middlelayer.AccRepository.Response;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository.Repositories.Interface;

namespace Siger.ApiACC.Controllers
{
    [NoTokenValidateFilter]
    public class AccController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerAccTraceRepository _sigerAccTrace;
        private readonly ISigerTrWasteRepository _trWaste;
        private readonly ISigerRoutingInStation _routingInStation;
        private readonly ISigerRoutingOutStation _routingOutStation;
        private readonly ISnListRepository _snList;
        private readonly ISigerRoutingEventNo _routingEventNo;
        private readonly ISigerProjectLevelSectionRepository _levelSection;
        private readonly ISigerTrReworkSnRepository _trReworkSn;
        private readonly ISigerTrSnTraceRepository _trSnTrace;
        private readonly ISigerDict _dict;
        private readonly ISigerTrPackBoxSNListRepository _packBoxSnList;
        private readonly ISigerTrPackBoxListRepository _packBoxList;

        public AccController(IUnitOfWork unitOfWork, ISigerAccTraceRepository sigerAccTrace,
            ISigerTrWasteRepository trWaste, ISnListRepository snList, ISigerRoutingInStation routingInStation,
            ISigerRoutingOutStation routingOutStation, ISigerRoutingEventNo routingEventNo, ISigerProjectLevelSectionRepository levelSection
            , ISigerTrReworkSnRepository trReworkSn, ISigerTrSnTraceRepository trSnTrace, ISigerDict dict, ISigerTrPackBoxSNListRepository packBoxSnList,
            ISigerTrPackBoxListRepository packBoxList
            )
        {
            _unitOfWork = unitOfWork;
            _sigerAccTrace = sigerAccTrace;
            _trWaste = trWaste;
            _snList = snList;
            _routingInStation = routingInStation;
            _routingOutStation = routingOutStation;
            _routingEventNo = routingEventNo;
            _levelSection = levelSection;
            _trReworkSn = trReworkSn;
            _trSnTrace = trSnTrace;
            _dict = dict;
            _packBoxSnList = packBoxSnList;
            _packBoxList = packBoxList;
        }
        /// <summary>
        /// 检查SN合法性
        /// </summary>
        /// <param name="requestSN"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult CheckSN([FromBody]RequestSN requestSN)
        {
            var pid = ProjectId;
            var BaseItem = _sigerAccTrace.GetBaseSetting(requestSN.SectionId, pid);
            if (BaseItem != null)
            {
                //打包是否需更新过站状态
                if (BaseItem.PackingBaseItem.Packing.Packing_NoCheckSn)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
                //检查报废件过站 不允许过站
                if (BaseItem.TraceBaseItem.Trace.NotAllowDebugSn)
                {
                    var exits = _trWaste.GetList(f =>
                        f.Line == BaseItem.Line && f.SN == requestSN.SN && f.projectId == pid && f.status == (int)RowState.Valid);
                    if (exits.Any())
                    {
                        throw new BadRequestException(AccEnum.Busi_DebugWasteSN);
                    }
                }
            }

            //var snlist = _snList.GetDataBySn(requestSN.SN, pid).FirstOrDefault();
            var snlist = _snList.Get(f => f.SN == requestSN.SN && f.projectId == pid);
            if (snlist == null)
            {

                throw new BadRequestException(AccEnum.Busi_SN_Null);
            }

            var routeIn = _routingInStation.Get(f =>
                f.Station == requestSN.SectionId && f.ProductId == snlist.ProductCode && f.projectId == pid && f.status == (int)RowState.Valid);

            if (routeIn == null)
            {
                Logger.WriteLineInfo(string.Format("工站:{0}未配置进站路由", requestSN.SectionId));
                throw new BadRequestException(AccEnum.Busi_SN_Routing_NG);
            }
            if (routeIn.ResultStatus != snlist.ResultStatus)
            {
                var outResult = _routingOutStation.Get(f => f.Line == BaseItem.Line && f.ResultStatus == snlist.ResultStatus && f.projectId == pid && f.status == (int)RowState.Valid);
                Logger.WriteLineInfo(string.Format("SN:{0}当前状态{1}", snlist.SN, snlist.ResultStatus));
                if (outResult != null)
                {
                    var evno = _routingEventNo.Get(f => f.EventNo == outResult.EventNo && f.projectId == pid && f.status == (int)RowState.Valid);
                    var station = _levelSection.Get(f => f.id == outResult.Station && f.projectid == pid && f.status == (int)RowState.Valid);
                    Logger.WriteLineInfo(string.Format("SN:{0}当前result{1}工站{2}", snlist.SN, evno.Descr, station.title));
                }
                throw new BadRequestException(AccEnum.Busi_SN_Routing_NG);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 返工功能 查询有效能够返工的SN
        /// </summary>
        /// <param name="sn"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult QuerySN(string sn)
        {
            var reworkSnList = new ResponseReworkSNList();
            var lstResult = _trReworkSn.GetList(f =>
                f.SN == sn && f.projectId == ProjectId && f.status == (int)RowState.Valid, "TransDateTime");

            if (!lstResult.Any())
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            foreach (var resultlist in lstResult)
            {
                var line = _levelSection.Get(f =>
                    f.id == resultlist.Line && f.projectid == ProjectId && f.status == (int)RowState.Valid);
                if (line == null)
                {
                    throw new BadRequestException(CommonEnum.NoData);
                }

                var fromStation = _levelSection.Get(f =>
                    f.id == resultlist.FromStation && f.projectid == ProjectId && f.status == (int)RowState.Valid);
                if (fromStation == null)
                {
                    throw new BadRequestException(CommonEnum.NoData);
                }
                var toStation = _levelSection.Get(f =>
                    f.id == resultlist.ToStation && f.projectid == ProjectId && f.status == (int)RowState.Valid);
                if (toStation == null)
                {
                    throw new BadRequestException(CommonEnum.NoData);
                }
                reworkSnList.reworkSNLists.Add(new reworkSNList
                {
                    ID = resultlist.id,
                    SN = resultlist.SN,
                    WO = resultlist.WO,
                    Line = line.title,
                    FromStation = fromStation.title,
                    FromStatus = resultlist.FromStatus,
                    ToStation = toStation.title,
                    ToStatus = resultlist.ToStatus,
                    Reason = resultlist.Reason,
                    TransDateTime = resultlist.TransDateTime.ToString("yyyy-MM-dd hh:nn:ss")
                });
            }
            return new ObjectResult(reworkSnList);
        }

        /// <summary>
        /// 获取两个小时内的组合检具检查
        /// </summary>
        /// <param name="obj">工位</param>
        /// <returns>返回两个小时内是否存在此工位的组合检具检查信息</returns>
        [HttpPost]
        public IActionResult HasCheckInfo([FromBody] RequestCheckInfo obj)
        {
            var OQCFCID = GetOQCFCID();
            if (OQCFCID == -1)
            {
                throw new BadRequestException((AccEnum.Data_OQCFC_Null));
            }

            var count = _trSnTrace.GetList(f =>
                f.Station == OQCFCID && f.TransDateTime > DateTime.Now.AddHours(obj.Hour) && f.projectId == ProjectId &&
                f.status == (int)RowState.Valid).Count();
            //两个小时内的SN中存在抽检记录
            if (count == 0)
            {
                throw new BadRequestException((AccEnum.EmtyResult));
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 获取最后一次组合抽检的时间
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetLastCheckTime([FromBody]RequestCheckInfo obj)
        {
            var OQCFCID = GetOQCFCID();
            if (OQCFCID == -1)
            {
                throw new BadRequestException((AccEnum.Data_OQCFC_Null));
            }

            var lastCheckInfo = _trSnTrace
                .GetList(f => f.Station == OQCFCID && f.projectId == ProjectId && f.status == (int)RowState.Valid,
                    "TransDateTime").FirstOrDefault();
            if (lastCheckInfo != null)
            {
                //取出指定SN在指定的时间内的最后抽检时间
                var date = lastCheckInfo.TransDateTime;
                if (date != null)
                {
                    return new ObjectResult(new { transDateTime = date });
                }
            }
            throw new BadRequestException((AccEnum.EmtyResult));
        }

        [HttpPost]
        public IActionResult GetHTPackingFullQTY()
        {
            var date = _dict.GetList(f =>
                f.cat == "htpackingfullqty" && f.projectId == ProjectId && f.status == (int)RowState.Valid);
            if (date != null)
            {
                return new ObjectResult(EnumHelper.GetEnumDesc(CommonEnum.Succefull));
            }
            throw new BadRequestException(AccEnum.EmtyResult);
        }

        /// <summary>
        /// 检测粗材打包的信息
        /// 如果sn存在于粗材打包的信息中
        /// 删除打包信息并检测是否存在其他信息,
        /// 如果无其他sn记录则更新box的status为清空
        /// </summary>
        [HttpPost]
        public IActionResult CheckAndUpdatePackBoxSN([FromBody]RequestCheckAndUpdatePackBoxSN req)
        {
            var queryPackBoxSNList = _packBoxSnList.GetList(f =>
                f.SN == req.SN && f.DeleteFlag == false && f.projectId == ProjectId &&
                f.status == (int)RowState.Valid);
            if (!queryPackBoxSNList.Any())
            {
                return new ObjectResult(EnumHelper.GetEnumDesc(CommonEnum.Succefull));
            }

            var packs = _packBoxList.GetList(f => f.Region == "" && f.status != PackStatus.Clear.GetHashCode())
                .Select(f => f.BoxID).ToList();
            if (packs.Count == 0)
            {
                return new ObjectResult(EnumHelper.GetEnumDesc(CommonEnum.Succefull));
            }

            var time = _packBoxSnList.GetList(f =>
                packs.Contains(f.BoxID) && f.DeleteFlag == false && f.projectId == ProjectId &&
                f.status == (int)RowState.Valid, "TransDateTime").FirstOrDefault();
            if (time == null)
            {
                return new ObjectResult(EnumHelper.GetEnumDesc(CommonEnum.Succefull));
            }
            //同一天
            var snData = _packBoxSnList.GetList(f =>
                f.SN == req.SN && f.DeleteFlag == false && f.projectId == ProjectId &&
                f.status == (int)RowState.Valid).FirstOrDefault();
            if (snData == null)
            {
                throw new BadRequestException(AccEnum.Data_Null);
            }
            if (snData.TransDateTime.Date > time.TransDateTime.Date)
            {
                throw new BadRequestException(AccEnum.HasEarlyData);
            }
            //当前记录为粗材打包
            var queryPackBoxList = _packBoxList.GetList(f =>
                f.BoxID == snData.BoxID && f.Region == "" && f.status != PackStatus.Clear.GetHashCode() &&
                f.projectId == ProjectId &&
                f.status == (int)RowState.Valid);
            if (queryPackBoxList.Any())
            {
                snData.DeleteFlag = true;
                _packBoxSnList.Update(snData);

                //更新数据后此boxid无其他sn记录,更新box.status为清空
                queryPackBoxSNList = _packBoxSnList.GetList(f => f.BoxID == snData.BoxID && f.DeleteFlag == false &&
                                                                 f.projectId == ProjectId &&
                                                                 f.status == (int)RowState.Valid);
                if (!queryPackBoxSNList.Any())
                {
                    var data = _packBoxList
                        .GetList(
                            f => f.BoxID == snData.BoxID && f.Region == "" &&
                                 f.status != PackStatus.Clear.GetHashCode(), "TransDateTime").FirstOrDefault();
                    data.status = PackStatus.Clear.GetHashCode();
                    _packBoxList.Update(data);
                    if (_unitOfWork.Commit() > 0)
                    {
                        return new ObjectResult(EnumHelper.GetEnumDesc(CommonEnum.Succefull));
                    }
                    return new ObjectResult(EnumHelper.GetEnumDesc(AccEnum.Update_Error));
                }
            }
            return new ObjectResult(EnumHelper.GetEnumDesc(CommonEnum.Succefull));
        }

        private int GetOQCFCID()
        {
            var ret = _dict.GetList(f =>
                f.cat == "2HStationID" && f.projectId == ProjectId && f.status == (int)RowState.Valid);
            if (ret.Any())
            {
                int id = -1;
                return id;
            }
            return -1;
        }
        [HttpGet]
        public IActionResult GetData() => new ObjectResult(_levelSection.GetList());
    }
}