using System;
using Microsoft.AspNetCore.Mvc;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Repository;
using System.Linq;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Request;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.Repository.Request;
using Siger.ApiQMS.Utility;
using System.Collections.Generic;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.Common.ModuleEnum;

namespace Siger.ApiQMS.Controllers
{
    public class TypeCountController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IQmsTypeCountSettingRepository _countSettingRepository;
        private readonly IInspectStandardRepository _inspectStandard;
        private readonly ISigerProjectLevelRepository _levelRepository;
        private readonly ISigerProjectLevelSectionRepository _levelSectionRepository;
        private readonly ISigerProjectProductRepository _productRepository;
        public TypeCountController(IUnitOfWork unitOfWork, IQmsTypeCountSettingRepository typeCountSettingRepository,
            IInspectStandardRepository inspectStandard, ISigerProjectLevelRepository levelRepository,
            ISigerProjectLevelSectionRepository levelSectionRepository, ISigerProjectProductRepository productRepository)
        {
            _unitOfWork = unitOfWork;
            _countSettingRepository = typeCountSettingRepository;
            _inspectStandard = inspectStandard;
            _levelRepository = levelRepository;
            _levelSectionRepository = levelSectionRepository;
            _productRepository = productRepository;
        }

        [HttpGet]
        public IActionResult GetTypeCounts(int page = PageIndex, int pagesize = PageSize)
        {
            var res = _countSettingRepository.GetList(t => t.projectid == ProjectId && t.status == (int) RowState.Valid).ToList();
           
            return new PagedObjectResult(res.Skip((page - 1) * pagesize).Take(pagesize).ToList(), res.Count, page, pagesize);
        }

        [HttpPost]
        public IActionResult AddTypeCount([FromBody]RequestAddTypeCount request)
        {
            var isExist = _countSettingRepository.IsExist(q => q.type_code == request.code.ToInt() && q.projectid == ProjectId && q.status == (int)RowState.Valid);
            if (isExist)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            isExist = _countSettingRepository.IsExist(q => q.type_name == request.name && q.projectid == ProjectId && q.status == (int)RowState.Valid);
            if (isExist)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }

            var entity = new siger_qms_type_count_setting
            {
                check_count = request.count.ToInt(),
                type_code = request.code.ToInt(),
                type_name = request.name,
                projectid = ProjectId,
                create_time = DateTime.Now
            };
            _countSettingRepository.Insert(entity);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult UpdateTypeCount([FromBody]RequestUpdateTypeCount request)
        {
            var set = _countSettingRepository.Get(request.id);
            if (set == null || set.status == (int)RowState.Invalid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            set.check_count = request.count.ToInt();
            set.type_name = request.name;
            _countSettingRepository.Update(set);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult DeleteTypeCount(int id)
        {
            var set = _countSettingRepository.Get(id);
            if (set == null || set.status == (int) RowState.Invalid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            set.status = (int) RowState.Invalid;
            _countSettingRepository.Update(set);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            throw new BadRequestException(CommonEnum.Fail);
        }

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

            foreach (var requestId in request.ids)
            {
                var set = _countSettingRepository.Get(requestId);
                if (set != null)
                {
                    set.status = (int)RowState.Invalid;
                    _countSettingRepository.Update(set);
                }
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 从检验项目表取工位得到产线结构
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSectionTreeByCheckType(string checktype)
        {
            var typeOne = checktype; var typeEnd = $",{typeOne}"; var typeStart = $"{typeOne},"; var typeTwo = $",{typeOne},";//精确匹配，避免类似12匹配到1的情况
            var itemSectionIds = _inspectStandard.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid
                && (t.checktype.Contains(",") ? (t.checktype.Contains(typeTwo) || t.checktype.StartsWith(typeStart) || t.checktype.EndsWith(typeEnd)) : (t.checktype == typeOne))).Select(t => t.sectionid).ToList();
            var levels = _levelRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
            var maxLevel = levels.Max(q => q.id);
            var sections = _levelSectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid);
            var itemSections = sections.Where(t => itemSectionIds.Contains(t.id) && t.levelid == maxLevel).ToList();
            var inSections = new List<siger_project_level_section>();
            foreach (var section in itemSections)
            {
                var parentSections = new List<siger_project_level_section>();
                int pid = section.parentid;
                foreach (var level in levels)
                {
                    if (level.id == maxLevel)
                    {
                        parentSections.Add(section);
                        pid = section.parentid;
                    }
                    else
                    {
                        var parentSection = sections.FirstOrDefault(t => t.id == pid);
                        if (parentSection != null)
                        {
                            pid = parentSection.parentid;
                            parentSections.Add(parentSection);
                        }
                    }
                }
                inSections.AddRange(parentSections);
            }
            inSections = inSections.GroupBy(t => t.id).Select(t => t.FirstOrDefault()).ToList();

            var resp = ChannelSectionHelper.GetSectionChildren(0, ProjectId, maxLevel, inSections);
            return new ObjectResult(resp);
        }

        [HttpGet]
        public IActionResult GetProductsByCheckType(string sectionid, string checktype)
        {
            var levels = _levelRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid).OrderByDescending(t => t.id).ToList();
            var levelSection = _levelSectionRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid && t.id == sectionid.ToInt());
            if (!levels.Any() || levelSection == null)
            {
                return new ObjectResult(new List<ResponseIdName>());
            }
            var sectionIds = new List<int>();
            if (levels[1].id > levelSection.levelid)
            {
                return new ObjectResult(new List<ResponseIdName>());
            }
            sectionIds = _levelSectionRepository.GetLevelSectionIds(sectionid.ToInt(), ProjectId).ToList();
            var typeOne = checktype; var typeEnd = $",{typeOne}"; var typeStart = $"{typeOne},"; var typeTwo = $",{typeOne},";//精确匹配，避免类似12匹配到1的情况
            var productIds = _inspectStandard.GetList(t => sectionIds.Contains(t.sectionid) && t.projectid == ProjectId &&
                t.status == (int)RowState.Valid && (t.checktype.Contains(",") ? (t.checktype.Contains(typeTwo) || t.checktype.StartsWith(typeStart) || t.checktype.EndsWith(typeEnd)) : (t.checktype == typeOne))).Select(t => t.productid).ToList();
            var products = _productRepository.GetList(t => productIds.Contains(t.id) && t.projectid == ProjectId &&
                t.status == (int)RowState.Valid).Select(t => new
                {
                    t.id,
                    t.name,
                    t.code
                }).ToList();

            return new ObjectResult(products);
        }

        [HttpGet]
        public IActionResult GetItemsByCheckType(string sectionid, string checktype, string productid)
        {
            var typeOne = checktype; var typeEnd = $",{typeOne}"; var typeStart = $"{typeOne},"; var typeTwo = $",{typeOne},";//精确匹配，避免类似12匹配到1的情况
            var items = _inspectStandard.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.sectionid == sectionid.ToInt() && (t.checktype.Contains(",") ? (t.checktype.Contains(typeTwo) || t.checktype.StartsWith(typeStart) || t.checktype.EndsWith(typeEnd)) : (t.checktype == typeOne)) && t.productid == productid.ToInt() &&
                t.ucl.HasValue && t.lcl.HasValue && t.value_type == (int)ValueTypeStatus.V)
                .Select(q => new ResponseIdName { id = q.id, name = q.item }).ToList();
            return new ObjectResult(items);
        }
    }
}