using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.AppSettings;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Request;
using Siger.Middlelayer.QmsRepository.Response;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.Repository.Entities;
using Siger.ApiQMS.Utility;
using Siger.ApiCommon.Filters;
namespace Siger.ApiQMS.Controllers
{
    public class InspectStandardController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IInspectStandardRepository _inspectStandard;
        private readonly IInspectUnhealthyRepository _inspectUnhealthy;
        private readonly ISigerProjectProductRepository _productRepository;
        private readonly ISigerProjectLevelSectionRepository _levelSectionRepository;
        private readonly ISigerProjectLevelRepository _levelRepository;
        private readonly IQmsTypeCountSettingRepository _typeCountRepository;
        private readonly ICheckSnTraceDetailRepository _inspectionDetailRepository;
        private readonly IInspectStandardOptionRepository _inspectStandardOptionRepository;
        private readonly IQmsTypeCountSettingRepository _countSettingRepository;
        public InspectStandardController(IUnitOfWork unitOfWork, IInspectStandardRepository inspectStandard,
            IInspectUnhealthyRepository inspectUnhealthy, ISigerProjectLevelSectionRepository levelSectionRepository, 
            ISigerProjectProductRepository productRepository, ISigerProjectLevelRepository levelRepository,
            IQmsTypeCountSettingRepository typeCountRepository, ICheckSnTraceDetailRepository inspectionDetailRepository,
            IInspectStandardOptionRepository inspectStandardOptionRepository, IQmsTypeCountSettingRepository countSettingRepository)
        {
            _unitOfWork = unitOfWork;
            _inspectStandard = inspectStandard;
            _inspectUnhealthy = inspectUnhealthy;
            _productRepository = productRepository;
            _levelSectionRepository = levelSectionRepository;
            _levelRepository = levelRepository;
            _typeCountRepository = typeCountRepository;
            _inspectionDetailRepository = inspectionDetailRepository;
            _inspectStandardOptionRepository = inspectStandardOptionRepository;
            _countSettingRepository = countSettingRepository;
        }

        [HttpGet]
        public IActionResult GetPageList(int productid, int sectionid, int page,int pagesize)
        {
            var sectionIds = new List<int>();
            if(sectionid > 0)
            {
                sectionIds = _levelSectionRepository.GetLevelSectionIds(sectionid, ProjectId).ToList();
            }
            var data = new List<RepsonseInspectStandard>();
            var res = _inspectStandard.GetPagedList(productid, sectionIds, ProjectId, page, pagesize);
            var levelSections = _levelSectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
            foreach(var item in res.Data)
            {
                if (item.value_type==3)
                {
                    var option = _inspectStandardOptionRepository.GetList(q => q.standardid == item.id && q.status == (int)RowState.Valid && q.projectid == ProjectId).ToList();
                    var list = new List<RequestOption>();
                    foreach (var items in option)
                    {
                        var options= new RequestOption();
                        options.option = items.option;
                        options.option_type = items.option_type;
                        list.Add(options);
                    }
                    item.data=list;
                }
                var model = Mapper<RepsonseInspectStandard, RepsonseInspectStandard>.Map(item);
                model.section_value = ChannelSectionHelper.GetChannelSection(item.sectionid, levelSections);
                model.checktype = model.check_type.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(t => t.ToInt()).ToList();
                model.check_type = GetCheckTypes(model.check_type);
                data.Add(model);
            }
            return new PagedObjectResult(data, res.Total, page, pagesize);
        }

        [HttpGet]
        public IActionResult GetStandard(int id)
        {
            var standard = _inspectStandard.GetData(id, ProjectId);
            if(standard != null)
            {
                var sections = new List<int>();
                var sectionIds = GetSectionIds(sections, standard.sectionid);
                sectionIds.Reverse();
                standard.sectionids = sectionIds;
                standard.checktype = standard.check_type.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(t => t.ToInt()).ToList();
            }
            return new ObjectResult(standard ?? new RepsonseInspectStandard());
        }

        private List<int> GetSectionIds(List<int> sectionIds, int parentId)
        {
            var section = _levelSectionRepository.Get(t => t.id == parentId && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if(section != null)
            {
                sectionIds.Add(section.id);
                return GetSectionIds(sectionIds, section.parentid);
            }
            else
            {
                return sectionIds;
            }
        }

        [HttpPost]
        public IActionResult Delete([FromBody]RequestDeleteParameter req)
        {
            if (req.ids == null || !req.ids.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }
            var models = _inspectStandard.GetList(t =>
                req.ids.Contains(t.id) && t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
            if (!models.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var isDelSuccess = false;
            var Ids = models.Select(q => q.id).ToList();
            var updatedIds = new List<int>();
            foreach (var model in models)
            {
                model.status = (int)RowState.Invalid;
                _inspectStandard.Update(model);
                var items = _inspectStandard.GetList(t =>
                    t.projectid == ProjectId && t.status == (int)RowState.Valid && t.sectionid == model.sectionid
                    && t.productid == model.productid && !Ids.Contains(t.id) && !updatedIds.Contains(t.id)).OrderBy(t => t.seq).ToList();
                updatedIds.AddRange(items.Select(t => t.id).ToList());
                if (items.Any())
                {
                    int i = 1;
                    foreach (var item in items)
                    {
                        item.seq = i;
                        _inspectStandard.Update(item);
                        i++;
                    }
                }
                if (_unitOfWork.Commit() > 0)
                {
                    isDelSuccess = true;
                }
            }
            if (isDelSuccess)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 报废 位置获取OQC产品
        /// </summary>
        /// <param name="sectionId"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetOQCItemProduct(int sectionId)
        {
            var res = new List<ResponseProductItem>();
            var staions = _levelSectionRepository.GetAccStationByline(ProjectId, sectionId).Select(s=>s.id).ToList();
            staions.Add(sectionId);
            var data = _inspectStandard.GetList(f => f.projectid == ProjectId && staions.Contains(f.sectionid) && f.status == (int)RowState.Valid).Select(f=>f.productid).Distinct();
            foreach(var d in data)
            {
                if (res.Exists(f => f.productId == d))
                    continue;
                var product = _productRepository.Get(f => f.projectid == ProjectId && f.id == d);
                if (product == null)
                    continue;
                res.Add(new ResponseProductItem
                {
                    productId = d,
                    productName = product.name
                });
            }
            return new ObjectResult(res);
        }
        /// <summary>
        /// 报废 位置获取OQC 检验项
        /// </summary>
        /// <param name="productid"></param>
        /// <param name="sectionid"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetItems(int productid, int sectionid)
        {
            var res = GetInspectsItems(ProjectId, productid, sectionid);
            return new ObjectResult(res);
        }
        /// <summary>
        /// 报废 位置获取OQC 检验项
        /// </summary>
        /// <param name="productCode">产品CODE</param>
        /// <param name="sectionid"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetItemsByProductCode(string productCode, int sectionid)
        {
            var product = _productRepository.Get(f => f.code == productCode && f.projectid==ProjectId && f.status==(int)RowState.Valid);
            if (product == null)
                throw new ClientException(EnumHelper.GetEnumDesc(CommonEnum.RecordNotFound));
            var res = GetInspectsItems(ProjectId, product.id, sectionid);
            return new ObjectResult(res);
        }
        /// <summary>
        /// C/S 端获取检验项
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="productCode"></param>
        /// <param name="sectionId"></param>
        /// <returns></returns>
        [HttpGet]
        [NoTokenValidateFilter]
        public IActionResult GetClientsItems(int projectId, string productCode,int sectionId)
        {

            var product = _productRepository.Get(f => f.code == productCode && f.projectid == projectId && f.status == (int)RowState.Valid);
            if (product == null)
                throw new ClientException(EnumHelper.GetEnumDesc(CommonEnum.RecordNotFound));

            var res = GetInspectsItems(projectId,product.id, sectionId);
            return new ObjectResult(res);
        }
        /// <summary>
        /// 获取标准检验项 检查项
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="productId"></param>
        /// <param name="sectionId"></param>
        /// <returns></returns>
        private List<ResponseOQCItem> GetInspectsItems(int projectId,int productId,int sectionId)
        {
            var res = new List<ResponseOQCItem>();
            var staions = _levelSectionRepository.GetLevelSectionIds(sectionId, projectId).Distinct().ToList();
            var datas = _inspectStandard.GetList(t =>
                t.productid == productId && staions.Contains(t.sectionid) &&
                t.projectid == projectId && t.status == (int)RowState.Valid);
            var items = datas.GroupBy(t => t.item).Select(t => t.FirstOrDefault()).ToList();
            foreach (var data in items)
            {
                if (res.Exists(f => f.id == data.id))
                    continue;
                res.Add(new ResponseOQCItem
                {
                    id = data.id,
                    item = data.item,
                    type=data.value_type,
                    max_val=data.max_value,
                    min_val=data.min_value,
                    unit=data.unit
                });
            }
            return res;
        }
        /// <summary>
        /// 相关检验数据展示
        /// </summary>
        /// <param name="productCode"></param>
        /// <param name="sectionid"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetItemsByParent(string productCode, int sectionid)
        {
            var res = new List<ResponseOQCItemTab>();
            var station = _levelSectionRepository.Get(f => f.id == sectionid);
            if (station==null)
                throw new BadRequestException(RequestEnum.StationIsEmpty);

            var staions = _levelSectionRepository.GetLevelSectionIds(station.parentid, ProjectId).Distinct().ToList();
            var datas = _inspectStandard.GetList(t =>t.productcode == productCode && staions.Contains(t.sectionid) && t.projectid == ProjectId && t.status == (int)RowState.Valid);

            var grpStation = datas.Where(f=>f.sectionid!=sectionid).GroupBy(g => g.sectionid);
            foreach(var st in grpStation)
            {
                var levelSection = _levelSectionRepository.Get(f => f.id == st.Key);
                var tab = new ResponseOQCItemTab
                {
                    Section = st.Key,
                    Title = levelSection != null ? levelSection.title : "",
                    Data = new List<ResponseOQCItemObjDts>()
                };
                var stDts = st.ToList();
                foreach(var dts in stDts)
                {
                    if (tab.Data.Exists(f => f.Id == dts.id))
                        continue;
                    tab.Data.Add(new ResponseOQCItemObjDts
                    {
                         Id=dts.id,
                         Value=dts.item
                    });
                }
                res.Add(tab);
            }

            return new ObjectResult(res);
        }
        [HttpPost]
        public IActionResult AddStandard([FromBody]RequestAddInspectStandard req)
        {
            var itemPinYin = PinYinHelper.ToPinYin(req.item);
            if (string.IsNullOrWhiteSpace(itemPinYin))
            {
                itemPinYin = req.item;
            }
            if (req.productid <= 0 || req.sectionid <= 0 || string.IsNullOrEmpty(req.item) || string.IsNullOrEmpty(itemPinYin) ||
                (req.value_type == (int)CheckType_Status.V && string.IsNullOrEmpty(req.max_value) &&
                 string.IsNullOrEmpty(req.min_value)) || string.IsNullOrEmpty(req.standard) || req.standard_type.ToInt() <= 0 ||
                 (req.checktype != null && !req.checktype.Any()) || (req.value_type == (int)CheckType_Status.V && 
                 (req.ucl.HasValue && !req.lcl.HasValue || !req.ucl.HasValue && req.lcl.HasValue)))
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }

            if (string.IsNullOrEmpty(req.max_value) && !string.IsNullOrEmpty(req.min_value) && req.value_type == (int)ValueTypeStatus.V)
            {
                req.max_value = QmsLimitValue.MaxValue;
            }
            if (!string.IsNullOrEmpty(req.max_value) && string.IsNullOrEmpty(req.min_value) && req.value_type == (int)ValueTypeStatus.V)
            {
                req.min_value = QmsLimitValue.MinValue;
            }
            var max = req.max_value.ToDouble();
            var min = req.min_value.ToDouble();
            if (req.value_type == (int)CheckType_Status.V)
            {
                if (max < min)
                {
                    throw new BadRequestException(RequestEnum.MaxMinError);
                }
            }
            if (req.ucl.HasValue && req.lcl.HasValue && req.ucl < req.lcl)
            {
                throw new BadRequestException(RequestEnum.UpperLowerError);
            }
            if (req.item.Length > 200)
            {
                throw new BadRequestException(RequestEnum.InspectItemExceedWordLimit);
            }
            if (req.standard.Length > 200)
            {
                throw new BadRequestException(RequestEnum.InspectStandardExceedWordLimit);
            }

            if ((req.value_category.ToInt() == (int)ValueCategory.Maxmin && string.IsNullOrEmpty(req.range)) || req.seq.ToInt() <= 0 ||
                (req.value_type == (int)ValueTypeStatus.V && req.value_category.ToInt() <= 0))
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }

            var maxLevel = _levelRepository.GetList(t => t.status == (int)RowState.Valid && t.projectid == ProjectId).Max(q => q.id);
            var section = _levelSectionRepository.Get(t => t.status == (int)RowState.Valid && t.projectid == ProjectId && t.id == req.sectionid);
            if(section == null || section.levelid != maxLevel)
            {
                throw new ServerException(1052);
            }

            var product = _productRepository.Get(t =>
                t.id == req.productid && t.status == (int)RowState.Valid && t.projectid == ProjectId);
            if (product == null)
            {
                throw new BadRequestException(RequestEnum.ProductidNotNull);
            }

            var unhealthyCode = _inspectUnhealthy.Get(t =>
                t.id == req.unhealthy_id && t.status == (int)RowState.Valid && t.projectid == ProjectId);
            if (unhealthyCode == null)
            {
                throw new BadRequestException(RequestEnum.UnhealthyCodeNotFound);
            }

            var querySeq = _inspectStandard.Get(t => t.sectionid == req.sectionid && t.productid == req.productid &&
                t.projectid == ProjectId && t.status == (int)RowState.Valid && t.seq == req.seq.ToInt() && 
                t.standard_type == req.standard_type.ToInt());
            if (querySeq != null)
            {
                throw new BadRequestException(RequestEnum.ItemSeqExsit);
            }

            var time = UnixTimeHelper.GetNow();
            var model = new siger_qms_inspection_standard
            {
                productid = product.id,
                productcode = product.code ?? "",
                sectionid = req.sectionid,
                standard = req.standard ?? "",
                seq = req.seq.ToInt(),
                item = req.item,
                item_en = itemPinYin,
                unit = req.value_type == (int)ValueTypeStatus.O ? "" : req.unit ?? "",
                max_value = req.value_type == (int)ValueTypeStatus.O ? 0 : Math.Round(max, 4),
                min_value = req.value_type == (int)ValueTypeStatus.O ? 0 : Math.Round(min, 4),
                unhealthy_desc = unhealthyCode.name ?? "",
                value_type = req.value_type,
                create_mid = UserId,
                create_time = time,
                update_mid = UserId,
                update_time = time,
                projectid = ProjectId,
                status = (int)RowState.Valid,
                unhealthy_id = unhealthyCode.id,
                unhealthy_code = unhealthyCode.code,
                value_category = req.value_category.ToInt(),
                range = req.range.ToDouble(),
                standard_type = req.standard_type.ToInt(),
                checktype = string.Join(',', req.checktype),
                ucl = req.ucl,
                lcl = req.lcl,
                trigger_andon = req.trigger_andon.ToInt()
            };
            _inspectStandard.Insert(model);
            if (_unitOfWork.Commit() > 0)
            {
                if (req.value_type == 3)
                {
                    foreach (var item in req.data)
                    {
                        var option = new siger_qms_inspection_standard_option
                        {
                            standardid = model.id,
                            option = item.option,
                            option_type = item.option_type,
                            projectid = ProjectId,
                            optionValue = req.value_type,
                        };
                        _inspectStandardOptionRepository.Insert(option);
                    }
                    _unitOfWork.Commit();
                }
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult EditStandard([FromBody]RequestEditInspectStandard req)
        {
            var model = _inspectStandard.Get(t => t.id == req.id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (model == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var itemPinYin = PinYinHelper.ToPinYin(req.item);
            if (string.IsNullOrWhiteSpace(itemPinYin))
            {
                itemPinYin = req.item;
            }
            if (string.IsNullOrEmpty(req.item) || string.IsNullOrEmpty(itemPinYin) ||
                (req.value_type == (int)CheckType_Status.V && string.IsNullOrEmpty(req.max_value) 
                && string.IsNullOrEmpty(req.min_value)) || string.IsNullOrEmpty(req.standard) || req.standard_type.ToInt() <= 0 ||
                (req.checktype != null && !req.checktype.Any()) || (req.value_type == (int)CheckType_Status.V && 
                (req.ucl.HasValue && !req.lcl.HasValue || !req.ucl.HasValue && req.lcl.HasValue)))
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }

            if (string.IsNullOrEmpty(req.max_value) && !string.IsNullOrEmpty(req.min_value) && req.value_type == (int)ValueTypeStatus.V)
            {
                req.max_value = QmsLimitValue.MaxValue;
            }
            if (!string.IsNullOrEmpty(req.max_value) && string.IsNullOrEmpty(req.min_value) && req.value_type == (int)ValueTypeStatus.V)
            {
                req.min_value = QmsLimitValue.MinValue;
            }
            var max = req.max_value.ToDouble();
            var min = req.min_value.ToDouble();
            if (req.value_type == (int)CheckType_Status.V)
            {
                if (max < min)
                {
                    throw new BadRequestException(RequestEnum.MaxMinError);
                }
            }
            if(req.ucl.HasValue && req.lcl.HasValue && req.ucl < req.lcl)
            {
                throw new BadRequestException(RequestEnum.UpperLowerError);
            }
            if (req.item.Length > 200)
            {
                throw new BadRequestException(RequestEnum.InspectItemExceedWordLimit);
            }
            if (req.standard.Length > 200)
            {
                throw new BadRequestException(RequestEnum.InspectStandardExceedWordLimit);
            }
            if ((req.value_category.ToInt() == (int)ValueCategory.Maxmin && string.IsNullOrEmpty(req.range)) || req.seq.ToInt() <= 0 ||
                (req.value_type == (int)ValueTypeStatus.V && req.value_category.ToInt() <= 0))
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }

            var maxLevel = _levelRepository.GetList(t => t.status == (int)RowState.Valid && t.projectid == ProjectId).Max(q => q.id);
            var section = _levelSectionRepository.Get(t => t.status == (int)RowState.Valid && t.projectid == ProjectId && t.id == req.sectionid);
            if (section == null || section.levelid != maxLevel)
            {
                throw new ServerException(1052);
            }

            var product = _productRepository.Get(t =>
                t.id == req.productid && t.status == (int)RowState.Valid && t.projectid == ProjectId);
            if (product == null)
            {
                throw new BadRequestException(RequestEnum.ProductidNotNull);
            }

            var unhealthyCode = _inspectUnhealthy.Get(t =>
                t.id == req.unhealthy_id && t.status == (int)RowState.Valid && t.projectid == ProjectId);
            if(unhealthyCode == null)
            {
                throw new BadRequestException(RequestEnum.UnhealthyCodeNotFound);
            }

            var querySeq = _inspectStandard.Get(t => t.sectionid == req.sectionid && t.productid == req.productid &&
                t.projectid == ProjectId && t.status == (int)RowState.Valid && t.seq == req.seq.ToInt() && t.id != req.id &&
                t.standard_type == req.standard_type.ToInt());
            if (querySeq != null)
            {
                throw new BadRequestException(RequestEnum.ItemSeqExsit);
            }
            if (model.value_type==3&& req.value_type!=3)
            {
                var option = _inspectStandardOptionRepository.GetList(q => q.standardid == model.id && q.status == (int)RowState.Valid && q.projectid==ProjectId).ToList();
                foreach (var item in option)
                {
                    item.status = (int)RowState.Invalid;
                    _inspectStandardOptionRepository.Update(item);
                }
            }else if (model.value_type != 3 && req.value_type == 3)
            {
                foreach (var item in req.data)
                {
                    var option = new siger_qms_inspection_standard_option
                    {
                        standardid = model.id,
                        option = item.option,
                        option_type = item.option_type,
                        projectid = ProjectId,
                        optionValue = req.value_type,
                    };
                    _inspectStandardOptionRepository.Insert(option);
                }

            }
            else if (model.value_type == 3 && req.value_type == 3)
            {
                var options = _inspectStandardOptionRepository.GetList(q => q.standardid == model.id && q.status == (int)RowState.Valid && q.projectid == ProjectId).ToList();
                foreach (var item in options)
                {
                    item.status = (int)RowState.Invalid;
                    _inspectStandardOptionRepository.Update(item);
                }
                foreach (var item in req.data)
                {
                    var option = new siger_qms_inspection_standard_option
                    {
                        standardid = model.id,
                        option = item.option,
                        option_type = item.option_type,
                        projectid = ProjectId,
                        optionValue = req.value_type,
                    };
                    _inspectStandardOptionRepository.Insert(option);
                }

            }
            var time = UnixTimeHelper.GetNow();
            model.standard = req.standard ?? "";
            model.item = req.item;
            model.item_en = itemPinYin;
            model.unit = req.value_type == (int)ValueTypeStatus.O ? "" : req.unit ?? "";
            model.max_value = req.value_type == (int)ValueTypeStatus.O ? 0 : Math.Round(max, 4);
            model.min_value = req.value_type == (int)ValueTypeStatus.O ? 0 : Math.Round(min, 4);
            model.unhealthy_code = unhealthyCode.code ?? "";
            model.unhealthy_desc = unhealthyCode.name ?? "";
            model.value_type = req.value_type;
            model.update_mid = UserId;
            model.update_time = time;
            model.unhealthy_id = req.unhealthy_id;
            model.productid = product.id;
            model.sectionid = section.id;
            model.value_category = req.value_category.ToInt();
            model.range = req.range.ToDouble();
            model.checktype = string.Join(',', req.checktype);
            model.standard_type = req.standard_type.ToInt();
            model.seq = req.seq.ToInt();
            model.ucl = req.ucl;
            model.lcl = req.lcl;
            model.trigger_andon = req.trigger_andon.ToInt();

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

        private string GetCheckTypes(string inpectcategories)
        {
            var dicts = GetAllCategoriess();
            var types = new List<string>();
            var categories = inpectcategories.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var category in categories)
            {
                foreach (KeyValuePair<string, int> dict in dicts)
                {
                    if (dict.Value.ToStr() == category)
                    {
                        types.Add(dict.Key);
                    }
                }
            }
            return string.Join(',', types);
        }

        private Dictionary<string, int> GetAllCategoriess()
        {
            var dict = new Dictionary<string, int>();
            var list = _countSettingRepository.GetList(q => q.status == 1 && q.projectid == ProjectId);
            foreach (var item in list.ToList())
            {
                dict.Add(item.type_name, item.type_code);
            }
            return dict;
        }
        [HttpGet]
        public IActionResult ExportExcelStandard(int productid, int sectionid)
        {
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
                        
            var sectionIds = new List<int>();
            if (sectionid > 0)
            {
                sectionIds = _levelSectionRepository.GetLevelSectionIds(sectionid, ProjectId).ToList();
            }
            var data = _inspectStandard.GetDataList(productid, sectionIds, ProjectId).ToList();
            if (!data.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var levelSections = _levelSectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
            var dataList = new List<InspectionStandardTemplates>();
            var count = 0;
            foreach (var item in data)
            {

                var Standard = new InspectionStandardTemplates();
                Standard.productcode = item.productcode;
                Standard.productname = item.productname;
                Standard.section = ChannelSectionHelper.GetChannelSection(item.sectionid, levelSections);
                Standard.seq = item.seq;
                Standard.item = item.item;
                Standard.standard = item.standard;
                Standard.value_type = item.value_type.ToString();
                Standard.unit = item.value_type == (int)ValueTypeStatus.V ? item.unit : "";
                Standard.max_value = item.value_type == (int)ValueTypeStatus.V ? (item.max_value.ToStr() == QmsLimitValue.MaxValue ? "" : item.max_value.ToStr()) : "";
                Standard.min_value = item.value_type == (int)ValueTypeStatus.V ? (item.min_value.ToStr() == QmsLimitValue.MinValue ? "" : item.min_value.ToStr()) : "";
                Standard.unhealthy_code = item.unhealthy_code;
                Standard.unhealthy_category = item.unhealthy_category_name;
                Standard.unhealthy_name = item.unhealthy_name;
                Standard.update_mid = item.update_mid;
                Standard.update_time = item.update_time;
                Standard.value_category = item.value_category.ToString();
                Standard.range = item.range.ToStr();
                Standard.isinpect = item.standard_type == 1 ? "人工检验" : "送检检验";
                Standard.inpectcategories = GetCheckTypes(item.check_type);
                Standard.trigger_andon = item.trigger_andon == 1 ? "是" : "否";
                Standard.ucl = item.value_type == (int)ValueTypeStatus.V ? (item.ucl.HasValue ? item.ucl.Value.ToString() : "") : "";
                Standard.lcl = item.value_type == (int)ValueTypeStatus.V ? (item.lcl.HasValue ? item.lcl.Value.ToString() : "") : "";
                
                if (item.value_type == 3)
                {
                    var list = _inspectStandardOptionRepository.GetList(q => q.standardid == item.id).ToList();
                    if (list != null)
                    {
                        var option = new RequestOption();
                        var num = 0;
                        foreach (var items in list)
                        {
                            option.option = items.option;
                            option.option_type= items.option_type;
                            item.data.Add(option);
                            num=num+2;
                        }
                        if (num > count)
                        {
                            count = num;
                        }
                    }
                    #region  赋值
                    if ((item.data.Count) * 2 < 3)
                    {
                        Standard.item1 = item.data[0].option;
                        Standard.item2 = item.data[0].option_type== 0?"NG":"OK";
                    }
                    if ((item.data.Count) * 2>2 && (item.data.Count) * 2 < 5)
                    {
                        Standard.item1 = item.data[0].option;
                        Standard.item2 = item.data[0].option_type == 0 ? "NG" : "OK";
                        Standard.item3 = item.data[1].option;
                        Standard.item4 = item.data[1].option_type == 0 ? "NG" : "OK";
                    }
                    if ((item.data.Count) * 2 > 5 && (item.data.Count) * 2 < 7)
                    {
                        Standard.item1 = item.data[0].option;
                        Standard.item2 = item.data[0].option_type == 0 ? "NG" : "OK";
                        Standard.item3 = item.data[1].option;
                        Standard.item4 = item.data[1].option_type == 0 ? "NG" : "OK";
                        Standard.item5 = item.data[2].option;
                        Standard.item6 = item.data[2].option_type == 0 ? "NG" : "OK";
                    }
                    if ((item.data.Count) * 2 > 7 && (item.data.Count) * 2 < 9)
                    {
                        Standard.item1 = item.data[0].option;
                        Standard.item2 = item.data[0].option_type == 0 ? "NG" : "OK";
                        Standard.item3 = item.data[1].option;
                        Standard.item4 = item.data[1].option_type == 0 ? "NG" : "OK";
                        Standard.item5 = item.data[2].option;
                        Standard.item6 = item.data[2].option_type == 0 ? "NG" : "OK";
                        Standard.item7 = item.data[3].option;
                        Standard.item8 = item.data[3].option_type == 0 ? "NG" : "OK";
                    }
                    if ((item.data.Count) * 2 > 9 && (item.data.Count) * 2 < 11)
                    {
                        Standard.item1 = item.data[0].option;
                        Standard.item2 = item.data[0].option_type == 0 ? "NG" : "OK";
                        Standard.item3 = item.data[1].option;
                        Standard.item4 = item.data[1].option_type == 0 ? "NG" : "OK";
                        Standard.item5 = item.data[2].option;
                        Standard.item6 = item.data[2].option_type == 0 ? "NG" : "OK";
                        Standard.item7 = item.data[3].option;
                        Standard.item8 = item.data[3].option_type == 0 ? "NG" : "OK";
                        Standard.item9 = item.data[4].option;
                        Standard.item10 = item.data[5].option_type == 0 ? "NG" : "OK";
                    }
                    #endregion
                }
                dataList.Add(Standard);
            }
            if (dataList.Any())
            {
                EpPlusExcelHelper<InspectionStandardTemplates> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<InspectionStandardTemplates>();
                    var temporaryFileName = $"检验标准维护信息_InspectionStandardInfo_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                    helper.GenerateExcels(dataList, Path.Combine(rootDir, temporaryFileName),count);
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("Export Inspection Standard Info failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }

            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetAllItems(int valueType = (int)ValueTypeStatus.V)
        {
            var items = _inspectStandard.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid
                 && (t.value_type == valueType && valueType > 0 || valueType == 0))
                .Select(q => new ResponseIdName { id = q.id, name = q.item }).ToList();
            return new ObjectResult(items);
        }

        [HttpGet]
        public IActionResult GetTemplate()
        {
            var fileSetting = Config<FileSettings>.Get();
            if (fileSetting == null)
            {
                throw new BadRequestException(CommonEnum.GetCommCfgFailed);
            }

            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder);
            

            return new ObjectResult(CreateInspectionStandardTemplate());
        }

        private string CreateInspectionStandardTemplate()
        {
            var columnNames = new List<string>();
            var titles = _levelRepository.GetLevelTitles(0, ProjectId);
            columnNames.AddRange(titles);

            var helper = new EpPlusForTpmHelper();
            var aa = _levelRepository.GetProjectLanguage(ProjectId);
            columnNames.AddRange(helper.GetTemplateColumns(typeof(InspectStandardLevelTemplate), _levelRepository.GetProjectLanguage(ProjectId)));
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            var temporaryFileName = $"InspectionStandardTemplate_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);
            helper.GenerateExcel(columnNames, fileName);
            
            return $"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}";
        }

        [HttpGet]
        public IActionResult GetProductsBySectionId(string sectionid, string reverselevel = "1")
        {
            if(reverselevel.ToInt() != 1 && reverselevel.ToInt() != 2)
            {
                return new ObjectResult(new List<ResponseIdName>());
            }
            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() || levels.Count < 2 || levelSection == null)
            {
                return new ObjectResult(new List<ResponseIdName>());
            }        
            var sectionIds = new List<int>();            
            if (reverselevel.ToInt() == 1)
            {
                if(levels[0].id != levelSection.levelid)
                {
                    return new ObjectResult(new List<ResponseIdName>());
                }
                sectionIds.Add(sectionid.ToInt());
            }
            else if(reverselevel.ToInt() == 2)
            {
                if (levels[1].id > levelSection.levelid)
                {
                    return new ObjectResult(new List<ResponseIdName>());
                }
                sectionIds = _levelSectionRepository.GetLevelSectionIds(sectionid.ToInt(), ProjectId).ToList();
            }            
            var productIds = _inspectStandard.GetList(t => sectionIds.Contains(t.sectionid) && t.projectid == ProjectId &&
                t.status == (int)RowState.Valid).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);
        }

        /// <summary>
        /// 从检验项目表取工位得到产线结构
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSectionTree()
        {
            var itemSectionIds = _inspectStandard.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid)
                .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 GetItemLevelSection(int reverselevel, int parentid)
        {
            var levels = _levelRepository.GetList(t => t.status == (int)RowState.Valid && t.projectid == ProjectId).OrderByDescending(t => t.id).ToList();
            if (levels.Count < reverselevel)
            {
                throw new BadRequestException(RequestEnum.LevelNotFound);
            }
            var res = _levelSectionRepository.GetSectionIdNamesByLevel(levels[reverselevel - 1].id, parentid, ProjectId).OrderBy(d=>d.name).ToList();
            foreach(var r in res)
            {
                var i = _levelSectionRepository.ConvetTitle(r.name);
                var indexStr =r.name.Substring(i, r.name.Length-i);
                int.TryParse(indexStr, out int _index);
                r.index = _index;
            }
            if (reverselevel == 2)
            {
                var itemSectionIds = _inspectStandard.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid)
                        .Select(t => t.sectionid).ToList();
                var channelIds = _levelSectionRepository.GetList(t => itemSectionIds.Contains(t.id)).Select(t => t.parentid).ToList();
                res = res.Where(t => channelIds.Contains(t.id)).ToList();
            }
            if (reverselevel == 1)
            {
                var itemSectionIds = _inspectStandard.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                        res.Select(q => q.id).Contains(t.sectionid)).Select(t => t.sectionid).ToList();
                res = res.Where(t => itemSectionIds.Contains(t.id)).OrderBy(o=>o.index).ToList();
            }
            return new ObjectResult(res);
        }
        [HttpGet]
        public IActionResult GetSectionByProduct(int line)
        {
            var stations = _levelSectionRepository.GetAccStationByline(ProjectId, line).Select(s => s.id).ToList();
            var oqcItem = _inspectStandard.GetList(f => f.projectid == ProjectId && f.status==(int)RowState.Valid && stations.Contains(f.sectionid)).GroupBy(g=>g.sectionid).Select(s=>s.FirstOrDefault()).ToList();
            var result = new List<ResponseKeyValue>();
            foreach (var o in oqcItem)
            {
                var level = _levelSectionRepository.Get(f => f.projectid == ProjectId && f.id == o.sectionid);
                result.Add(new ResponseKeyValue(o.sectionid.ToStr(), level.title));
            }
            return new ObjectResult(result);
        }

        [HttpGet]
        public IActionResult GetAllCheckItemNameList()
        {
            var itemIds = _inspectionDetailRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid).
                Select(t => t.ItemID).Distinct().ToList();
            var items = _inspectStandard.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                itemIds.Contains(t.id)).Select(q => new ResponseIdName { id = q.id, name = q.item }).
                GroupBy(t => t.name).Select(t => t.FirstOrDefault()).ToList();
            return new ObjectResult(items);
        }

        /// <summary>
        /// 编辑页面获取详情
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetDetails(int productid, int sectionid, int checktype)
        {
            var res = new ResponseDataCollectionDetailList();
            var typeOne = checktype.ToString(); var typeEnd = $",{typeOne}"; var typeStart = $"{typeOne},"; var typeTwo = $",{typeOne},";//精确匹配，避免类似12匹配到1的情况
            var standards = _inspectStandard.GetList(t =>
                t.productid == productid && t.sectionid == sectionid && t.projectid == ProjectId
                && t.status == (int)RowState.Valid && t.standard_type == (int)StandardType.ManualCollection &&
                (t.checktype.Contains(",") ? (t.checktype.Contains(typeTwo) || t.checktype.StartsWith(typeStart) || t.checktype.EndsWith(typeEnd)) : (t.checktype == typeOne))).OrderBy(q => q.seq).ToList();
            foreach (var standard in standards)
            {
                var model = new ResponseDataCollectionDetails
                {
                    id = 0,
                    itemid = standard.id,
                    max_value = standard.max_value,
                    min_value = standard.min_value,
                    result = "",
                    value = null,
                    item = standard.item,
                    standard = standard.standard,
                    checktype = standard.value_type,
                    valuecategory = standard.value_category,
                    range = standard.range,
                };
                res.details.Add(model);
            }
            var tyepCount = _typeCountRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.type_code == checktype);
            res.quantity = tyepCount?.check_count ?? 0;
            return new ObjectResult(res);
        }

        /// <summary>
        /// QMS  质量分析BI 检验项关联性分析
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult BIResult([FromBody]RequestBIAnalysis request)
        {
            var tracking = new ResponseBIResult { Heads = new List<BIAnalysStation>(), Bodys = new List<BIAnalysStation>() };


            return new ObjectResult(tracking);

        }
    }
}