using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.CncRepository.Entities;
using Siger.Middlelayer.CncRepository.Repositories.Interface;
using Siger.Middlelayer.CncRepository.Request;
using Siger.Middlelayer.CncRepository.Response;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Request;
using Siger.ApiCommon.Filters;
namespace Siger.ApiCNC.Controllers
{
    public class BeatAllocationController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IProductionBeatSetRepository _beatSetRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerProjectProductRepository _productRepository;
     
        public BeatAllocationController(IUnitOfWork unitOfWork, IProductionBeatSetRepository beatSetRepository, ISigerProjectMachineRepository machineRepository,
            ISigerProjectProductRepository productRepository)
        {
            _unitOfWork = unitOfWork;
            _beatSetRepository = beatSetRepository;
            _machineRepository = machineRepository;
            _productRepository = productRepository;
        }

        [HttpGet]
        public IActionResult ShowBeatAllocation(int sectionID, string product_name_text, string drawing_number, int page = 1, int pagesize = 10)
        {
            var data = _beatSetRepository.GetPagedList(sectionID, product_name_text, drawing_number, ProjectId, page,
                pagesize);
            var list = new List<ResponseBeatSet>();

            var validMachines = _machineRepository.GetLevelSectionNames(sectionID, ProjectId);
            foreach (var time in data.Data)
            {
                var entity = Mapper<ResponseBeatSet, ResponseBeatSet>.Map(time);
                var section = validMachines.FirstOrDefault(q => q.machine_id == time.machineID);
                if (section != null)
                {
                    entity.sectionName = section.machine_name;
                    entity.stationName = section.lastSecondSectionTitle + "-" + section.lastSectionTitle;
                }
                list.Add(entity);
            }
            return new PagedObjectResult(list, data.Total, page, pagesize);
        }

        [HttpPost]
        public async Task<IActionResult> AddBeatAllocation([FromBody]RequestAddBeatAllocation request)
        {
            if (request.standard_besat == 0)
            {
                throw new ServerException(800292);
            }
            if (request.daily_standard_output == 0)
            {
                throw new ServerException(800293);
            }

            var start = request.start_time.ToDateTime();
            var end = request.end_time.ToDateTime().AddDays(1).AddSeconds(-1);

            var entities = await _beatSetRepository.GetListAsync(q=>q.status == (int)RowState.Valid && q.process_number == request.program_number
                                                   && q.machineID == request.machineID && q.projectID == ProjectId);
            if (entities.Any())
            {
                var beats = entities.ToList();
                foreach (var beat in beats)
                {
                    if (start >= beat.start_time && start <= beat.end_time)
                    {
                        throw new ServerException(940009);
                    }
                    if (end >= beat.start_time && end <= beat.end_time)
                    {
                        throw new ServerException(940009);
                    }
                    if (start <= beat.start_time && end >= beat.end_time)
                    {
                        throw new ServerException(940009);
                    }
                }
            }

            var product = _productRepository.Get(q =>
                q.id == request.product_name.ToInt() && q.projectid == ProjectId && q.status == (int) RowState.Valid);
            if (product == null)
            {
                throw new BadRequestException(RequestEnum.ProductNotFound);
            }
            var beatSet = new siger_project_beat_set
            {
                daily_standard_output = request.daily_standard_output,
                drawing_number = product.drawingcode,
                add_time = DateTime.Now,
                machineID = request.machineID,
                process_number = request.program_number,
                product_name_text = product.name,
                product_name = request.product_name,
                section_id = request.sectionid,
                standard_besat = request.standard_besat,
                projectID = ProjectId,
                changemodeltime = request.time_num.ToInt(),
                route_number = request.route_number.ToStr(),
                route_name = request.route_name,
                updown_besat = request.updown_besat.ToDouble(),
                yieldrate = request.yieldratio,
                start_time = start,
                end_time = end
            };
            await _beatSetRepository.InsertAsync(beatSet);
            if (await _unitOfWork.CommitAsync() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public async Task<IActionResult> EditBeatAllocation([FromBody]RequestEditBeatAllocation request)
        {
            if (request.standard_besat == 0)
            {
                throw new ServerException(800292);
            }
            if (request.daily_standard_output == 0)
            {
                throw new ServerException(800293);
            }

            var start = request.start_time.ToDateTime();
            var end = request.end_time.ToDateTime().AddDays(1).AddSeconds(-1);

            var entities = await _beatSetRepository.GetListAsync(q => q.status == (int)RowState.Valid && q.process_number == request.program_number
                                                                                                      && q.machineID == request.machineID && q.projectID == ProjectId
                                                                                                      && q.id != request.id);
            if (entities.Any())
            {
                var beats = entities.ToList();
                foreach (var beat in beats)
                {
                    if (start >= beat.start_time && start <= beat.end_time)
                    {
                        throw new ServerException(940009);
                    }
                    if (end >= beat.start_time && end <= beat.end_time)
                    {
                        throw new ServerException(940009);
                    }
                    if (start <= beat.start_time && end >= beat.end_time)
                    {
                        throw new ServerException(940009);
                    }
                }
            }
             
            var beatSet = await _beatSetRepository.GetAsync(request.id);
            if (beatSet == null || beatSet.status != (int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            beatSet.daily_standard_output = request.daily_standard_output;
            beatSet.edit_time = DateTime.Now;
            //beatSet.machineID = request.machineID;
            //beatSet.section_id = request.sectionid;
            beatSet.standard_besat = request.standard_besat;
            beatSet.changemodeltime = request.time_num.ToInt();
            //beatSet.route_number = request.route_number.ToStr();
            //beatSet.route_name = request.route_name;
            beatSet.updown_besat = request.updown_besat.ToDouble();
            beatSet.yieldrate = request.yieldratio;
            beatSet.start_time = request.start_time.ToDateTime();
            beatSet.end_time = request.end_time.ToDateTime().AddDays(1).AddSeconds(-1);

            await _beatSetRepository.UpdateAsync(beatSet);
            if (await _unitOfWork.CommitAsync() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult DelBeatAllocation(int id)
        {
            var beatSet = _beatSetRepository.Get(id);
            if (beatSet == null || beatSet.status != (int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            beatSet.status = (int)RowState.Invalid;
            _beatSetRepository.Update(beatSet);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult DeleteMultipleBeats([FromBody] RequestDeleteEntities request)
        {
            if (request.ids == null || !request.ids.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            var times = _beatSetRepository.GetList(q => request.ids.Contains(q.id) && q.projectID == ProjectId).ToList();
            foreach (var time in times)
            {
                time.status = (int)RowState.Invalid;
                _beatSetRepository.Update(time);
            }

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

        /// <summary>
        /// 查询产品工序 -- 长龄
        /// </summary>
        /// <param name="section"></param>
        /// <param name="productCode"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetBeatRoute(int section,string productCode)
        {
            var product = _productRepository.Get(f => f.projectid == ProjectId && f.code == productCode);
            if (product == null)
                throw new BadRequestException(CommonEnum.RecordNotFound);
            var beatSets = _beatSetRepository.GetList(f => f.projectID == ProjectId && f.section_id==section && f.product_name == product.id.ToStr());
            var results = new List<ResponseBeatRoute>();
            foreach (var set in beatSets)
            {
                results.Add(new ResponseBeatRoute {
                     Id =set.id,
                     Route=set.route_name
                });
            }
            return new ObjectResult(results);
        }
        /// <summary>
        /// C 端 获取工艺 
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="section"></param>
        /// <param name="productCode"></param>
        /// <returns></returns>
        [HttpGet]
        [NoTokenValidateFilter]
        public IActionResult GetBeatSet(int projectId,int section,string productCode)
        {
            var product = _productRepository.Get(f => f.projectid == projectId && f.code == productCode);
            if (product == null)
                throw new ClientException(EnumHelper.GetEnumDesc(CommonEnum.RecordNotFound));
            var beatSets = _beatSetRepository.GetList(f => f.projectID == projectId && f.section_id == section && f.product_name == product.id.ToStr());
            if (!beatSets.Any())
                throw new ClientException(EnumHelper.GetEnumDesc(CommonEnum.RecordNotFound));
            var results = new List<ResponseBeatRoute>();
            foreach (var set in beatSets)
            {
                results.Add(new ResponseBeatRoute
                {
                    Id = set.id,
                    Route = set.route_name
                });
            }
            return new ObjectResult(results);
        }

    }
}