using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.WmsRepository.Repositories.Interface;
using Siger.Middlelayer.WmsRepository.Request;

namespace Siger.ApiWMS.Controllers
{
    /// <summary>
    /// 入库单、出库单管理
    /// </summary>
    public class WaveHousingController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly Isiger_wms_stock_access_orderRepository order;
        private readonly Isiger_wms_stock_access_order_detailRepository orderdetail;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="unitOfWork"></param>
        /// <param name="order"></param>
        /// <param name="orderdetail"></param>
        public WaveHousingController(IUnitOfWork unitOfWork, Isiger_wms_stock_access_orderRepository order, Isiger_wms_stock_access_order_detailRepository orderdetail)
        {
            _unitOfWork = unitOfWork;
            this.order = order;
            this.orderdetail = orderdetail;
        }

        /// <summary>
        /// 入库单汇总
        /// </summary>
        /// <returns></returns>
        public IActionResult GetWaveHousingBills(WaveHouseType type, WaveHousingState orderstatus, int page = 1, int pageSize = 10)
        {
            Utility.CheckPage(page, pageSize);
            var result = order.GetWaveHousingBills(ProjectId, type, orderstatus, page, pageSize, out int totalCount);
            return new PagedObjectResult(result, totalCount, page, pageSize);
        }
        /// <summary>
        /// 获取单号列表
        /// </summary>
        /// <param name="type"></param>
        /// <param name="storageid"></param>
        /// <returns></returns>
        public IActionResult GetBillCodes(WaveHouseType type, int storageid)
        {
            return new ObjectResult(order.GetBillCodes(type, ProjectId, storageid));
        }

        /// <summary>
        /// 物料列表
        /// </summary>
        /// <param name="type"></param>
        /// <param name="billCode"></param>
        /// <param name="pn"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public IActionResult GetInventoryNameList(WaveHouseType type, string billCode,string pn,int count)
        {
            if (string.IsNullOrEmpty(billCode))
            {
                var data = orderdetail.GetInventoryList(ProjectId).GroupBy(t => t.pn).Select(t => t.FirstOrDefault())
                    .Select(f => new ResponseIdName { id = f.id, name = f.pn }).Take(count);

                return new ObjectResult(data);
            }
            else
            {
                var orderData = order.Get(f => f.status == (int)RowState.Valid && f.projectid == ProjectId && f.order_number == billCode);

                if (orderData == null)
                {
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                }

                var data = orderdetail.GetList(f => f.status == (int)RowState.Valid && f.projectid == ProjectId && f.orderid == orderData.id)
                    .GroupBy(t=>t.material_pn).Select(t=>t.FirstOrDefault()).Distinct().ToList()
                    .Select(f => new ResponseIdName { id = f.material_id, name = f.material_pn });
                if (!string.IsNullOrWhiteSpace(pn))
                {
                    data = data.Where(f => f.name.Contains(pn));
                }
                if (count!=0)
                {
                    data = data.Take(count).ToList();
                }
                return new ObjectResult(data);
            }

        }

        /// <summary>
        /// 入库单管理列表
        /// </summary>
        /// <param name="bill">出库、入库</param>
        /// <param name="waveHouseType">类型</param>
        /// <param name="waveHouseID">仓库名称</param>
        /// <param name="state">状态</param>
        /// <param name="billCode">单号</param>
        /// <param name="originBillCode"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IActionResult GetList(WaveHouseType bill, WaveHousingType waveHouseType, int waveHouseID, WaveHousingState state,
                                        string billCode, string originBillCode, DateTime start, DateTime end, int page = 1, int pageSize = 10)
        {
            Utility.CheckPage(page, pageSize);
            if (bill == WaveHouseType.In)
            {
                if (state == WaveHousingState.WaveHousingOut || state == WaveHousingState.WaveHousingOutFinish)
                {
                    throw new BadRequestException(RequestEnum.ErrorWaveHouseType);
                }
            }
            if (bill == WaveHouseType.Out)
            {
                if (state == WaveHousingState.WaveHousing || state == WaveHousingState.Finish)
                {
                    throw new BadRequestException(RequestEnum.ErrorWaveHouseType);
                }
            }
            var result = order.GeList(ProjectId, bill, waveHouseType, waveHouseID, state, billCode, originBillCode, start, end, out int totalCount, page, pageSize).ToList();            
            return new PagedObjectResult(result, totalCount, page, pageSize);
        }
        /// <summary>
        /// 入库状态列表
        /// </summary>
        /// <returns></returns>
        public IActionResult GetWavehousingState()
        {
            var dic = new List<kv>();
            modify(dic, WaveHousingState.Waiting);
            modify(dic, WaveHousingState.Checked);
            modify(dic, WaveHousingState.Failed);
            modify(dic, WaveHousingState.WaveHousing);
            modify(dic, WaveHousingState.Finish);
            return new ObjectResult(dic);
        }
        /// <summary>
        /// 出库状态列表
        /// </summary>
        /// <returns></returns>
        public IActionResult GetWavehouseOutState()
        {
            var dic = new List<kv>();
            modify(dic, WaveHousingState.Waiting);
            modify(dic, WaveHousingState.Checked);
            modify(dic, WaveHousingState.Failed);
            modify(dic, WaveHousingState.WaveHousingOut);
            modify(dic, WaveHousingState.WaveHousingOutFinish);
            return new ObjectResult(dic);
        }
        /// <summary>
        /// 获取部门列表
        /// </summary>
        /// <returns></returns>
        public IActionResult GetDepartmentList()
        {
            return new ObjectResult(order.GetDepartmentList(ProjectId));
        }
        /// <summary>
        /// 获取入库类型
        /// </summary>
        /// <returns></returns>
        public IActionResult GetWavehousingTypeList()
        {
            var dic = new List<kv>();
            modify(dic, WaveHousingType.RawMaterial);
            modify(dic, WaveHousingType.Production);
            modify(dic, WaveHousingType.Other);
            return new ObjectResult(dic);
        }
        /// <summary>
        /// 获取出库类型
        /// </summary>
        /// <returns></returns>
        public IActionResult GetWavehouseOutTypeList()
        {
            var result = new List<kv>();
            modify(result, WaveHousingType.ProductionOut);
            modify(result, WaveHousingType.SalesOut);
            modify(result, WaveHousingType.OtherOut);
            return new ObjectResult(result);
        }
        private void modify(List<kv> dic, WaveHousingState state)
        {
            dic.Add(new kv { k = (int)state, v = EnumHelper.GetEnumDesc(state) });
        }
        private void modify(List<kv> dic, WaveHousingType state)
        {
            dic.Add(new kv { k = (int)state, v = EnumHelper.GetEnumDesc(state) });
        }

        /// <summary>
        /// 删除出入库单
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult DeleteBill([FromBody]RequestDelBusiness req)
        {
            //只删除未审核的数据
            if (!order.IsExist(f => f.status == (int)RowState.Valid && f.id == req.id && f.order_status == (int)WaveHousingState.Waiting && f.projectid == ProjectId))
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var entity = order.Get(f => f.id == req.id && f.projectid == ProjectId);
            entity.status = (int)RowState.Invalid;
            entity.update_time = DateTime.Now;
            entity.updator = UserId;
            order.Update(entity);

            if (_unitOfWork.Commit() > 0)
                return Ok();
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 新增出入库单
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddBill([FromBody]RequestAddBill req)
        {
            //原始单号不填的话默认和单号一致
            if (string.IsNullOrEmpty(req.rowBillID))
            {
                req.rowBillID = req.billID;
            }
            //检测数量
            if (req.inventories.Where(f => f.Count <= 0).Count() > 0)
            {
                throw new BadRequestException(RequestEnum.CountError);
            }
            var inventories = req.inventories.Select(f => f.InventoryID);
            order.CheckInventory(inventories, ProjectId);
            var userid = req.picker.ToInt() > 0 ? req.picker.ToInt() : UserId;
            order.AddBill(ProjectId, req.billType, req.rowBillID, req.wavehousingtype, req.businessid, req.waveHouseID, req.rowBillID, req.inventories, ProjectId, UserId, userid, req.departid);
            return Ok();
        }
        /// <summary>
        /// 获取物料信息
        /// </summary>
        /// <param name="pn"></param>
        /// <param name="storage"></param>
        /// <param name="businessid"></param>
        /// <returns></returns>
        public IActionResult GetInventoryInfo(string pn,int storage,int businessid)
        {
            return new ObjectResult(order.GetInventoryInfo(pn, ProjectId, storage, businessid));
        }
        /// <summary>
        /// 更新单据信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UpdateBill([FromBody]RequestUpdateBill req)
        {
            order.UpdateBill(req.billID, req.inventories, ProjectId, UserId, req.picker.ToInt());
            return Ok();
        }
        /// <summary>
        /// 审核
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult CheckWaveHousing([FromBody]RequestCheck req)
        {
            //只审核未审核的数据
            if (!order.IsExist(f => f.status == (int)RowState.Valid && f.id == req.id && f.order_status == (int)WaveHousingState.Waiting && f.projectid == ProjectId))
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var entity = order.Get(f => f.id == req.id && f.projectid == ProjectId);
            if (req.pass)
            {
                entity.order_status = (int)WaveHousingState.Checked;
            }
            else
            {
                entity.order_status = (int)WaveHousingState.Failed;
            }
            entity.audit_desc = req.des;
            entity.update_time = DateTime.Now;
            entity.updator = UserId;
            entity.auditor = UserId;
            entity.audit_time = DateTime.Now;
            order.Update(entity);

            if (_unitOfWork.Commit() > 0)
                return Ok();
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 反审
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UnCheckWaveHousing([FromBody]RequestUncheck req)
        {
            //只反审核已审核的数据
            if (!order.IsExist(f => f.status == (int)RowState.Valid && f.id == req.id && f.projectid == ProjectId))
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var entity = order.Get(f => f.id == req.id && f.projectid == ProjectId);

            if (entity.order_status != (int)WaveHousingState.Checked && entity.order_status != (int)WaveHousingState.Failed)
            {
                throw new BadRequestException(RequestEnum.UncheckDeny);
            }

            entity.order_status = (int)WaveHousingState.Waiting;
            entity.auditor = UserId;
            entity.audit_desc = req.des;
            entity.audit_time = DateTime.Now;
            entity.update_time = DateTime.Now;
            entity.updator = UserId;
            order.Update(entity);

            if (_unitOfWork.Commit() > 0)
                return Ok();
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 获取原始单号列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetOriginOrderNumbers(int type)
        {
            var orders = order.GetList(t => t.projectid == ProjectId && t.status == (int) RowState.Valid && (t.access_type == type || type == 0)).Select(t =>
                new
                {
                    t.id,
                    t.origin_order_number
                }).OrderByDescending(t => t.id).ToList();
            return new ObjectResult(orders);
        }
    }
}