using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.AppSettings;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.Log;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Request;
using Siger.Middlelayer.QmsRepository.Response;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Request;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiQMS.Controllers
{
    public class SendTestParameterController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISendTestParameterRepository _parameterRepository;
        private readonly ISigerProjectMachineAttributionRepository _sigerProjectMachineAttribution;
        private readonly ISigerProjectLevelSectionRepository _sigerProjectLevelSection;
        private readonly ISigerDict _sigerDict;

        public SendTestParameterController(IUnitOfWork unitOfWork, ISendTestParameterRepository parameterRepository,
            ISigerDict sigerDict, ISigerProjectMachineAttributionRepository sigerProjectMachineAttribution,
            ISigerProjectLevelSectionRepository sigerProjectLevelSection)
        {
            _unitOfWork = unitOfWork;
            _parameterRepository = parameterRepository;
            _sigerProjectMachineAttribution = sigerProjectMachineAttribution;
            _sigerProjectLevelSection = sigerProjectLevelSection;
            _sigerDict = sigerDict;
        }

        [HttpGet]
        public IActionResult GetPageParameters(int sectionId, int page, int pagesize)
        {
            var stationIds = _sigerProjectMachineAttribution.GetSonLevelSections(sectionId, ProjectId).Select(s => s.id).ToList();
            stationIds.Add(sectionId);
            var res = _parameterRepository.GetSendTestParameters(stationIds, ProjectId, page, pagesize, 0);
            foreach (var data in res.Data)
            {
                data.section_name = GetAllTitle(data.section_id);
                if (!string.IsNullOrWhiteSpace(data.parameters))
                {
                    var keys = data.parameters.Split(',').ToList();
                    var dicts = _sigerDict.GetList(t => t.projectId == ProjectId && t.status == (int)RowState.Valid &&
                                                        keys.Contains(t.dkey) && t.cat == AccDictCost.SendTestParameter);
                    data.parameter_names = string.Join(",", dicts.Select(t => t.dval).ToList());
                }
            }
            return new PagedObjectResult(res.Data, res.Total, page, pagesize);
        }

        private string GetAllTitle(int sectionId)
        {
            var titles = _sigerProjectLevelSection.GetLevelSectionTitles(sectionId, ProjectId);
            var list = titles.ToList();
            return list.Any() ? string.Join('-', list) : string.Empty;
        }

        [HttpPost]
        public IActionResult AddParameters([FromBody]RequestUpdateParameters request)
        {
            //唯一性验证
            var isExist = _parameterRepository.Get(q => q.projectid == ProjectId && q.status == (int) RowState.Valid
                                                                                 && q.section_id == request.section_id 
                                                                                 && q.serial_number == request.serial_number.ToInt());
            if (isExist != null)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            isExist = _parameterRepository.Get(q => q.projectid == ProjectId && q.status == (int)RowState.Valid
                                                                                 && q.section_id == request.section_id
                                                                                 && q.name == request.name);
            if (isExist != null)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }

            var entity = new siger_qms_sendtest_parameter
            {
                category = request.category.ToInt(),
                is_required = request.is_required.ToInt(),
                name = request.name,
                parameters = request.parameters,
                serial_number = request.serial_number.ToInt(),
                update_mid = UserId,
                update_time = DateTime.Now,
                section_id = request.section_id,
                projectid = ProjectId
            };
            _parameterRepository.Insert(entity);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult UpdateParameters([FromBody]RequestUpdateParameters request)
        {
            var set = _parameterRepository.Get(request.id);
            if (set == null || set.status == (int)RowState.Invalid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            //唯一性验证
            var isExist = _parameterRepository.Get(q => q.projectid == ProjectId && q.status == (int)RowState.Valid && q.section_id == request.section_id
                                                                                 && q.serial_number == request.serial_number.ToInt() && q.id != request.id);
            if (isExist != null)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            isExist = _parameterRepository.Get(q => q.projectid == ProjectId && q.status == (int)RowState.Valid && q.section_id == request.section_id
                                                                             && q.name == request.name && q.id != request.id);
            if (isExist != null)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }

            set.category = request.category.ToInt();
            set.is_required = request.is_required.ToInt();
            set.name = request.name;
            set.parameters = request.parameters;
            set.serial_number = request.serial_number.ToInt();
            set.update_mid = UserId;
            set.update_time = DateTime.Now;
            _parameterRepository.Update(set);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

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

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

        [HttpGet]
        public IActionResult ExportParameters(int sectionId)
        {
            
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
           
            var stationIds = _sigerProjectMachineAttribution.GetSonLevelSections(sectionId, ProjectId).Select(s => s.id).ToList();
            stationIds.Add(sectionId);
            var products = _parameterRepository.GetSendTestParameters(stationIds, ProjectId, 0, 0, 1);
            if (!products.Data.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            foreach (var data in products.Data)
            {
                data.section_name = GetAllTitle(data.section_id);
            }
            var temporaryFileName = $"parameter_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);

            var helper = new EpPlusExcelHelper<SendTestingParameterList>();
            try
            {
                var productList = new List<SendTestingParameterList>();
                foreach (var pro in products.Data.ToList())
                {
                    var keys = pro.parameters.Split(',').ToList();
                    var dicts = _sigerDict.GetList(t => t.projectId == ProjectId && t.status == (int)RowState.Valid &&
                                                        keys.Contains(t.dkey) && t.cat == AccDictCost.SendTestParameter);
                    pro.parameter_names = string.Join(",", dicts.Select(t => t.dval).ToList());
                    var product = new SendTestingParameterList
                    {
                        Category = pro.category == 1 ? "输入框" : "单选框",
                        IsRequired = pro.is_required == 1 ? "是" : "否",
                        Location = pro.section_name,
                        Paratemters = pro.parameter_names,
                        SerialNumber = pro.serial_number.ToStr(),
                        Name = pro.name,
                        UpdateTime = pro.update_time,
                        Updator = pro.updator
                    };
                    productList.Add(product);
                }

                helper.GenerateExcel(productList, fileName);
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("Export Parameter failed, error: " + e.Message);
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper.Dispose();
            }
        }

        [HttpGet]
        public IActionResult GetParameters(int sectionid)
        {
            var list = _parameterRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.section_id == sectionid).ToList();

            var res = new List<ResponseTestParameter>();
            foreach(var item in list)
            {
                var keys = item.parameters.Split(',').ToList();
                var dicts = _sigerDict.GetList(t => t.projectId == ProjectId && t.status == (int)RowState.Valid &&
                    keys.Contains(t.dkey) && t.cat == AccDictCost.SendTestParameter);
                res.Add(new ResponseTestParameter
                {
                    id = item.id,
                    category = item.category,
                    is_required = item.is_required,
                    name = item.name,
                    parameters = dicts.Select(t => new ResponseKeyValue(t.dkey, t.dval)).ToList()
                });
            }

            return new ObjectResult(res);
        }
    }

}