using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Filters;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Log;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.TlmRepository.Entities;
using Siger.Middlelayer.TlmRepository.Repositories.Interface;
using Siger.Middlelayer.TlmRepository.Request;
using Siger.Middlelayer.WmsRepository.Repositories.Interface;
using Siger.Middlelayer.WmsRepository.Request;

namespace Siger.ApiChangLing.Controllers
{
    [NoTokenValidateFilter]
    public class TlmClientController : BaseController
    {
        private const int projectId = 136;

        private readonly ISigerProjectUserRepository _userRepository;
        private readonly ISigerProjectSectionRepository _sectionRepository;
        private readonly ISigerProjectProductRepository _productRepository;
        private readonly IProductRouteRepository _routeRepository;
        private readonly IToolLifeTechnologyRepository _technologyRepository;
        private readonly IToolLifeToolTechRepository _lifeToolRepository;
        private readonly Isiger_wms_settingsRepository _settingsRepository;
        private readonly Isiger_wms_stock_access_orderRepository _orderRepository;
        private readonly ISigerDict _sigerDict;
        private readonly ISigerTrMaterialsRepository _materialsRepository;
        private readonly IToollifeCabinetConfigRepository _cabinetConfig;
        private readonly IToollifeCabinetReceiveRepository _cabinetReceive;
        private readonly IToollifeCabinetReceiveDetailRepository _cabinetReceiveDetail;
        private readonly ISigerTrMaterialsRepository _materials;

        public TlmClientController(ISigerProjectUserRepository userRepository, ISigerProjectSectionRepository sectionRepository,
            ISigerProjectProductRepository productRepository, IProductRouteRepository routeRepository,
            IToolLifeTechnologyRepository technologyRepository, IToolLifeToolTechRepository lifeToolRepository,
            Isiger_wms_settingsRepository settingsRepository, ISigerDict sigerDict, Isiger_wms_stock_access_orderRepository orderRepository,
            ISigerTrMaterialsRepository materialsRepository, IToollifeCabinetReceiveRepository cabinetReceive, IToollifeCabinetReceiveDetailRepository cabinetReceiveDetail,
            IToollifeCabinetConfigRepository cabinetConfig, IUnitOfWork unitOfWork, ISigerTrMaterialsRepository materials)
        {
            _userRepository = userRepository;
            _sectionRepository = sectionRepository;
            _productRepository = productRepository;
            _routeRepository = routeRepository;
            _technologyRepository = technologyRepository;
            _lifeToolRepository = lifeToolRepository;
            _settingsRepository = settingsRepository;
            _sigerDict = sigerDict;
            _orderRepository = orderRepository;
            _materialsRepository = materialsRepository;
            _cabinetReceive = cabinetReceive;
            _cabinetReceiveDetail = cabinetReceiveDetail;
            _cabinetConfig = cabinetConfig;
            _materials = materials;
        }

        [HttpGet]
        public IActionResult GetAllSections()
        {
            var sections = _sectionRepository.GetList(q => q.status == (int)RowState.Valid && q.projectid == projectId && q.type == 1) //生产部门
                .Select(m => new
                {
                    m.id,
                    m.title,
                    m.description
                }).ToList();
            return new ObjectResult(sections);
        }

        [HttpGet]
        public IActionResult GetAllUsers(int sectionId = 0)
        {
            return new ObjectResult(_userRepository.GetSectionUserList(sectionId, projectId));
        }

        [HttpGet]
        public IActionResult GetUserByCode(string code = "")
        {
            var user = _userRepository.Get(q =>
                q.work_code == code && q.projectid == projectId && q.status == (int)RowState.Valid);
            if (user == null)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpGet]
        public IActionResult GetAllProducts()
        {
            var products = _productRepository.GetList(q => q.projectid == projectId && q.status == (int)RowState.Valid)
                .Select(m => new
                {
                    m.id,
                    m.name,
                    m.drawingcode,
                    m.remark
                }).ToList();
            return new ObjectResult(products);
        }

        [HttpGet]
        public IActionResult GetProductRoutes(int productId = 0)
        {
            var routes = _routeRepository.GetList(q => q.projectId == projectId && q.status == (int)RowState.Valid
                                                                                && q.productId == productId)
                .Select(m => new
                {
                    m.id,
                    m.serialNumber,
                    m.name
                }).ToList();
            return new ObjectResult(routes);
        }

        [HttpGet]
        public IActionResult GetAllTools(int productId, int routeId)
        {
            var technology = _technologyRepository.Get(q => q.product_id == productId && q.route_id == routeId && q.status == (int)RowState.Valid
                && q.project_id == projectId);
            if (technology == null)
            {
                throw new BadRequestException(RequestEnum.TechnologyNotFound);
            }

            return new ObjectResult(_lifeToolRepository.GetToolCategories(technology.id, projectId));
        }

        [HttpPost]
        public IActionResult OutStock([FromBody]RequestOutStockForChangling req)
        {
            //获取billId
            var billId = _settingsRepository.GetBillIDs(Settings.WaveHouseOutPre, projectId);
            if (string.IsNullOrEmpty(billId))
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            //取出库类型
            var type = 10;  //领用出库
            var list = _sigerDict.GetList(f => f.cat == "outgoing_type" && f.status == (int)RowState.Valid && f.projectId == projectId, "dkey").ToList();
            if (list.Any())
            {
                var first = list.FirstOrDefault(q => q.dval == req.type);
                if (first != null)
                {
                    type = first.dkey.ToInt();
                }
                else
                {
                    var use = list.FirstOrDefault(q => q.dval == "领用出库");
                    if (use != null)
                    {
                        type = use.dkey.ToInt();
                    }
                    else
                    {
                        throw new BadRequestException(CommonEnum.Fail);
                    }
                }
            }

            //用户
            var user = _userRepository.Get(q => q.work_code == req.usercode && q.projectid == projectId && q.status == (int)RowState.Valid);
            if (user == null)
            {
                throw new BadRequestException(RequestEnum.UserNotFound);
            }

            foreach (var item in req.details.Select(f => f.InventoryID).ToList())
            {
                if (_materialsRepository.Get(f => f.pn == item && f.projectId == projectId && f.status == (int)RowState.Valid) == null)
                {
                    throw new BadRequestException(RequestEnum.MaterialNotExist);
                }
            }
            _orderRepository.AddBillForChangling(projectId, WaveHouseType.Out, billId, (WaveHousingType)type, 0, req.waveHouseID, req.billcode, req.details, projectId, user.id, user.id);
            return new ObjectResult(CommonEnum.Succefull);
        }
        /// <summary>
        /// 刀具柜领用接口
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ReceiveTools([FromBody]RequestReceiveTool request)
        {
            //工号有效性校验
            var userData = _userRepository.Get(f =>
                  f.work_code.Equals(request.userCode) && f.status == RowState.Valid.GetHashCode() &&
                  f.projectid.Equals(projectId));
            if (userData == null)
            {
                Logger.WriteLineInfo($"刀具柜领用接口{request.userCode}工号不存在");
                throw new BadRequestException(CommonEnum.Fail);
            }
            //刀柜有效性校验
            var cabinetData = _cabinetConfig.Get(f =>
                f.Cabinetcode.Equals(request.waveHouseId) && f.status == RowState.Valid.GetHashCode() &&
                f.project_id.Equals(projectId));
            if (cabinetData == null)
            {
                Logger.WriteLineInfo($"刀具柜领用接口{request.waveHouseId}道具柜不存在");
                throw new BadRequestException(CommonEnum.Fail);
            }
            //去重
            var query = _cabinetReceive.Get(f =>
                f.Billcode.Equals(request.Billcode) && f.Cabinetcode.Equals(request.waveHouseId) &&
                f.status != CabinetReceiveStatus.Closed.GetHashCode());
            if (query != null)
            {
                Logger.WriteLineInfo($"刀具柜领用接口{request.Billcode}道具柜领用记录已存在");
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            //插入receiveData
            var receiveData = new SigerProjectToollifeCabinetReceive
            {
                Billcode = request.Billcode,
                Type = request.Type,
                Usercode = request.userCode,
                Cabinetcode = request.waveHouseId,
                project_id = projectId,
                status = CabinetReceiveStatus.NoSettlement.GetHashCode(),
                Transtime = DateTime.Now,
            };
            var result = _cabinetReceive.InertCabinetReceiveData(receiveData);
            if (result == 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            //插入receiveData
            query = _cabinetReceive.Get(f =>
                f.Billcode.Equals(request.Billcode) && f.Cabinetcode.Equals(request.waveHouseId) &&
                f.status == CabinetReceiveStatus.NoSettlement.GetHashCode());
            foreach (var item in request.Details)
            {
                var mData = _materials.Get(f =>
                            f.pn.Equals(item.inventoryID) && f.projectId.Equals(projectId) &&
                            f.status != (int)RowState.Invalid);
                if (mData==null)
                {
                    Logger.WriteLineInfo($"刀具柜领用接口{item.inventoryID}物料不存在存在");
                    _cabinetReceive.DeleteCabinetReceiveData(query.id);
                    throw new BadRequestException(CommonEnum.Fail);
                }
                var receiveDetail = new SigerProjectToollifeCabinetReceiveDetail
                {
                    Count = item.Count,
                    Inventoryid = item.inventoryID,
                    project_id = projectId,
                    status = RowState.Valid.GetHashCode(),
                    Name = _cabinetReceive.GetMaterial(0, item.inventoryID, projectId).name ?? "",
                    Mid = query.id,
                    Price = mData.price,
                    Supplier = cabinetData.Suppliercode
                };
                result = _cabinetReceiveDetail.InsertCabinetReceiveDetailData(receiveDetail);
            }


            if (result == 0)
            {
                _cabinetReceive.DeleteCabinetReceiveData(query.id);
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }
        /// <summary>
        /// 结算
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SubmitSettlement([FromBody]RequestCabinetReceiveData request)
        {
            var settleData =
                _cabinetReceive.Get(f => f.id.Equals(request.Id) && f.project_id.Equals(projectId) && f.status == (int)CabinetReceiveStatus.NoSettlement);
            if (settleData == null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var configData = _cabinetConfig.Get(f =>
                  f.Cabinetcode.Equals(settleData.Cabinetcode) && f.project_id.Equals(projectId) &&
                  f.status != (int)RowState.Invalid);
            if (configData == null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            //var detail =
            //    _cabinetReceiveDetail.GetList(f => f.Mid.Equals(request.Id) && f.project_id.Equals(projectId));

            #region //Erp数据库直接操作
            //SettlementRepository settlement = new SettlementRepository();
            //var dataDetail = new List<CabinetReceiveDetail>();
            //foreach (var data in detail)
            //{
            //    var mData = _materials.Get(f =>
            //        f.pn.Equals(data.Inventoryid) && f.projectId.Equals(projectId) &&
            //        f.status != (int)RowState.Invalid);
            //    CabinetReceiveDetail cabinetReceive = new CabinetReceiveDetail
            //    {
            //        Count = data.Count,
            //        Inventoryid = data.Inventoryid,
            //        Price = mData.price,
            //        Supplier = mData.supplier,
            //    };
            //    dataDetail.Add(cabinetReceive);
            //}
            //settlement.InsertSettlementData(configData.Suppliercode, dataDetail);
            #endregion
            settleData.status = (int)CabinetReceiveStatus.WaitSettlement;
            settleData.Uid = UserId;
            settleData.Settletime = DateTime.Now;
            var result = _cabinetReceive.UpdateCabinetReceiveData(settleData);
            if (result == 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }
    }
}