using AutoMapper;
using LinqKit;
using Microsoft.AspNetCore.NodeServices;
using Newtonsoft.Json;
using Ropin.Inspection.Common.Accessor.Interface;
using Ropin.Inspection.Common.Helper;
using Ropin.Inspection.Model;
using Ropin.Inspection.Model.Entities;
using Ropin.Inspection.Model.SearchModel.DEV;
using Ropin.Inspection.Model.ViewModel.DEV;
using Ropin.Inspection.Repository;
using Ropin.Inspection.Repository.DEV.Interface;
using Ropin.Inspection.Repository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Ropin.Inspection.Service
{
    public class TdevWebScadaDevSpotService : ITdevWebScadaDevSpotService
    {
        private readonly ITdevWebScadaDevSpotRepository _repository;
        private readonly IMapper _mapper;
        private readonly IClaimsAccessor _claims;
        private readonly INodeServices _services;
        private readonly IDevBoxRepository _devBoxRepository;
        public TdevWebScadaDevSpotService(IClaimsAccessor claims, INodeServices services, ITdevWebScadaDevSpotRepository repository, IMapper mapper, IDevBoxRepository devBoxRepository)
        {
            _repository = repository;
            _mapper = mapper;
            _claims = claims;
            _services = services;
            _devBoxRepository= devBoxRepository;
        }
        public async Task CreateAsync(TdevWebScadaDevSpotCreateModel viewModel)
        {
            var content = _mapper.Map<TDEV_WebScadaDevSpot>(viewModel);
            content.C_ID = Guid.NewGuid().ToString();
            content.C_CreateBy = _claims.ApiUserId;
            content.D_CreateOn = DateTime.Now;
            content.C_Status = "1";
            content.C_Type = "1";
            List<CalFormula> calFormulaList = new List<CalFormula>();
            if (viewModel.IsCalFormula)
            {
                if (!string.IsNullOrWhiteSpace(viewModel.C_CalFormula))
                {
                    var  calsList = JsonConvert.DeserializeObject<List<CalFormula>>(viewModel.C_CalFormula);
                    if (calsList!=null&& calsList.Count>0)
                    {
                        calFormulaList.AddRange(calsList);
                    }
                }
            }
            if (!string.IsNullOrWhiteSpace(viewModel.MinValue) || !string.IsNullOrWhiteSpace(viewModel.MaxValue))
            {
                //content.C_CalFormula = "./wwwroot/uploads/scripts/changecolour," + viewModel.MinValue +","+ viewModel.MaxValue;


                Queue<string> qu = new Queue<string>();
                qu.Enqueue(viewModel.MinValue);
                qu.Enqueue(viewModel.MaxValue);
                calFormulaList.Add(new CalFormula { Name = "changecolour", Value = qu });

                //calFormulaList.Add(new CalFormula { Name = "alarmlight", Value = qu });
                //content.C_CalFormula = JsonHelper.GetJSON<List<CalFormula>>(calFormulaList);
                //content.C_CalFormula = JsonConvert.SerializeObject(calFormulaList);
            }
            if (!string.IsNullOrWhiteSpace(viewModel.FMinValue) || !string.IsNullOrWhiteSpace(viewModel.FMaxValue))
            {
                Queue<string> qu = new Queue<string>();
                qu.Enqueue(viewModel.FMinValue);
                qu.Enqueue(viewModel.FMaxValue);
                calFormulaList.Add(new CalFormula { Name = "minchangecolour", Value = qu });
            }
            if (!string.IsNullOrWhiteSpace(viewModel.AlarmValue))
            {
                //List<CalFormula> calFormulaList = new List<CalFormula>();
                Queue<string> qu = new Queue<string>();
                qu.Enqueue(viewModel.AlarmValue);
                calFormulaList.Add(new CalFormula { Name = "alarmlight", Value = qu });
                //content.C_CalFormula = JsonConvert.SerializeObject(calFormulaList);
            }
            if (calFormulaList.Any())
                content.C_CalFormula = JsonConvert.SerializeObject(calFormulaList);
            else
                content.C_CalFormula = @"[{'Name':'noformula','Value':['']}]";
            content.C_ControlID = "ControlID" + content.C_ID;
            content.C_DevSpotCode = content.C_ID;
            _repository.Create(content);
            var result = await _repository.SaveAsync();
            if (result)
            {
                if (viewModel.boxCodeList != null && viewModel.boxCodeList.Count > 0)
                {
                    foreach (var item in viewModel.boxCodeList)
                    {
                        TDEV_DevBox devBox = new TDEV_DevBox();
                        devBox.C_ID = Guid.NewGuid().ToString();
                        devBox.C_BoxCode = item;
                        devBox.C_DevStoreCode = content.C_DevCode;
                        devBox.C_CreateBy = _claims.ApiUserId.ToString();
                        devBox.D_CreateOn = DateTime.Now;
                        devBox.C_Creator = _claims.ApiUserName;
                        _devBoxRepository.Create(devBox);
                    }
                    var devBoxResult = await _devBoxRepository.SaveAsync();
                }
            }
            else
            {
                throw new Exception("创建失败");
            }
        }

        //public async Task DeleteAsync(string id)
        //{
        //    var content = await _repository.GetByIdAsync(id);
        //    if (content == null)
        //    {
        //        throw new Exception("数据库中没有此数据");
        //    }
        //    //_repository.Delete(content);
        //    //var result = await _repository.SaveAsync();
        //    content.C_LastUpdatedBy = _claims.ApiUserId;
        //    content.D_LastUpdatedOn = DateTime.Now;
        //    content.C_Status = "0";
        //    _repository.Update(content);
        //    var result = await _repository.SaveAsync();
        //    if (!result)
        //    {
        //        throw new Exception("删除失败");
        //    }
        //}
        public async Task DeleteAsync(string code)
        {
            var items = await _repository.GetByConditionAsync(C => C.C_ID == code);
            var content = items.FirstOrDefault();
            if (content == null)
            {
                throw new Exception("没有此数据");
            }
            content.C_LastUpdatedBy = _claims.ApiUserId;
            content.D_LastUpdatedOn = DateTime.Now;
            content.C_Status = "0";
            _repository.Update(content);
            var result = await _repository.SaveAsync();
            if (!result)
            {
                throw new Exception("删除失败");
            }
        }
        public async Task DeleteDataAsync(string code)
        {
            var items = await _repository.GetByConditionAsync(C => C.C_ID == code);
            var content = items.FirstOrDefault();
            if (content == null)
            {
                throw new Exception("没有此数据");
            }
            _repository.Delete(content);
            var result = await _repository.SaveAsync();
            if (!result)
            {
                throw new Exception("删除失败");
            }
        }
        public async Task<IEnumerable<TdevWebScadaDevSpotViewModel>> GetAllAsync()
        {
            var pagedList = await _repository.GetAllAsync();
            var contentDtoList = _mapper.Map<IEnumerable<TdevWebScadaDevSpotViewModel>>(pagedList.Where(i => i.C_Status == "1").ToList());
            return contentDtoList.ToList();
        }
        public async Task<IEnumerable<TdevWebScadaDevSpotViewModel>> GetConditionAsync(TdevWebScadaDevSpotSearchModel searchModel)
        {
            var list = await _repository.GetConditionAsync(searchModel);
            var dtoList = _mapper.Map<List<TDEV_WebScadaDevSpotEndity>, List<TdevWebScadaDevSpotViewModel>>(list?.ToList());
            return dtoList;
        }

        public async Task<string> GetWebScadaByAsync(string devId)
        {
            var predicate = PredicateBuilder.New<TDEV_WebScadaDevSpot>(true);//查询条件,推荐后台使用这种方式灵活筛选
            predicate = predicate.And(i => i.C_Status.Equals("1"));
            predicate = predicate.And(i => i.C_DevCode.Equals(devId));
            var items = await _repository.GetByConditionAsync(predicate);
            var list = items.ToList();
            StringBuilder sb = new StringBuilder();
            for (int i=0; i<list.Count;i++)
            {
                sb.Append(GetRichTextBoxWebScadaById(i));    
            }

            return sb.ToString();
        }
        string GetRichTextBoxWebScadaById(int index)
        {
            int baseTop = 820;
            int top = baseTop + index * 100;
            string strIndex = index.ToString();
            string webScada = @"<input name='RichTextBox" + strIndex + @"' type='text' id='RichTextBox" + strIndex + @"' v-model='device.value" + strIndex + @"' style='width:160px;height: 80px;z-index:129;position:absolute;top: " + top + @"px;left:761px;font-size:32px; ' /><span id='Lable" + strIndex + @"' style='width:700px;height: 63px;z-index:126;position:absolute;top: " + strIndex + 10 + @"px;left:0px;font-size:32px;'>{{device.name" + strIndex + @"}}</span>";
            return webScada;
        }

        public async Task<string> GetWebScadaDevSpotValue(string devId)
        {
            var predicate = PredicateBuilder.New<TDEV_WebScadaDevSpot>(true);//查询条件,推荐后台使用这种方式灵活筛选
            predicate = predicate.And(i => i.C_Status.Equals("1"));
            predicate = predicate.And(i => i.C_DevCode.Equals(devId));
            var items = await _repository.GetByConditionAsync(predicate);
            if (!items.Any())
                return String.Empty;
            List<string> names = items.Select(x => x.C_Name).ToList();
            List<string> groupnames = items.Select(x => x.C_GroupName).ToList();
            List<string> calFormula = items.Select(x =>  x.C_CalFormula ).ToList();
            List<List<CalFormula>> calFormulaList = new List<List<CalFormula>>();
            //var calFormulaList = JsonConvert.DeserializeObject<List<List<CalFormula>>>(JsonConvert.SerializeObject(calFormula));
  
            foreach (var v in calFormula)
            {
                if(v != null)
                calFormulaList.Add(JsonConvert.DeserializeObject<List<CalFormula>>(v));
            }
            if (calFormulaList.Count ==0)
            {
                calFormulaList = null;
                calFormula = null;
            }
            string boxno = items.Select(x => x.C_BoxNo).FirstOrDefault();
            string storeCode = items.Select(x => x.C_StoreCode).FirstOrDefault();

            //List <List<CalFormula>> calFormulaList = items.Select(x => { var v= JsonConvert.DeserializeObject<List<CalFormula>>(x.C_CalFormula);return v; }).ToList();
            return await FanyiHelper.GetWebScadaDevSpotValue(devId, boxno, storeCode, names, groupnames, calFormula, _services, calFormulaList);
        }
        public async Task<string> GetWebScadaDevSpotHisData(string devId)
        {
            return await FanyiHelper.GetWebScadaDevSpotHisData(devId,null,null);
        }
     
        public async Task<TdevWebScadaDevSpotViewModel> GetByIdAsync(string id)
        {
            var content = await _repository.GetByIdAsync(id);
            var contentDto = _mapper.Map<TdevWebScadaDevSpotViewModel>(content);
            return contentDto;
        }


        public async Task UpdateAsync(string code, TdevWebScadaDevSpotUpdateModel updateModel)
        {
            var items = await _repository.GetByConditionAsync(C => C.C_ID == code);
            var content = items.FirstOrDefault();
            if (content == null)
            {
                throw new Exception("没有此数据");
            }
            content.C_LastUpdatedBy = _claims.ApiUserId;
            content.D_LastUpdatedOn = DateTime.Now;
            _mapper.Map(updateModel, content, typeof(TdevWebScadaDevSpotUpdateModel), typeof(TDEV_WebScadaDevSpot));
            List<CalFormula> calFormulaList = new List<CalFormula>();
            if (updateModel.IsCalFormula)
            {
                if (!string.IsNullOrWhiteSpace(updateModel.C_CalFormula))
                {
                    var calsList = JsonConvert.DeserializeObject<List<CalFormula>>(updateModel.C_CalFormula);
                    if (calsList != null && calsList.Count > 0)
                    {
                        calFormulaList.AddRange(calsList);
                    }
                }
            }
            if (!string.IsNullOrWhiteSpace(updateModel.MinValue) || !string.IsNullOrWhiteSpace(updateModel.MaxValue))
            {
                //content.C_CalFormula = "./wwwroot/uploads/scripts/changecolour," + viewModel.MinValue +","+ viewModel.MaxValue;


                Queue<string> qu = new Queue<string>();
                qu.Enqueue(updateModel.MinValue);
                qu.Enqueue(updateModel.MaxValue);
                calFormulaList.Add(new CalFormula { Name = "changecolour", Value = qu });

                //calFormulaList.Add(new CalFormula { Name = "alarmlight", Value = qu });
                //content.C_CalFormula = JsonHelper.GetJSON<List<CalFormula>>(calFormulaList);
                //content.C_CalFormula = JsonConvert.SerializeObject(calFormulaList);
            }
            if (!string.IsNullOrWhiteSpace(updateModel.FMinValue) || !string.IsNullOrWhiteSpace(updateModel.FMaxValue))
            {
                Queue<string> qu = new Queue<string>();
                qu.Enqueue(updateModel.FMinValue);
                qu.Enqueue(updateModel.FMaxValue);
                calFormulaList.Add(new CalFormula { Name = "minchangecolour", Value = qu });
            }
            if (!string.IsNullOrWhiteSpace(updateModel.AlarmValue))
            {
                //List<CalFormula> calFormulaList = new List<CalFormula>();
                Queue<string> qu = new Queue<string>();
                qu.Enqueue(updateModel.AlarmValue);
                calFormulaList.Add(new CalFormula { Name = "alarmlight", Value = qu });
                //content.C_CalFormula = JsonConvert.SerializeObject(calFormulaList);
            }
            if (calFormulaList.Any())
                content.C_CalFormula = JsonConvert.SerializeObject(calFormulaList);
            else
                content.C_CalFormula = @"[{'Name':'noformula','Value':['']}]";
            content.C_ControlID = "ControlID" + content.C_ID;
            content.C_DevSpotCode = content.C_ID; 

            _repository.Update(content);
            var result = await _repository.SaveAsync();
            if (result)
            {
                await _devBoxRepository.DeleteBYDevStoreCode(content.C_DevCode);
                if (updateModel.boxCodeList!=null&& updateModel.boxCodeList.Count>0)
                {
                    foreach (var item in updateModel.boxCodeList)
                    {
                        TDEV_DevBox devBox = new TDEV_DevBox();
                        devBox.C_ID = Guid.NewGuid().ToString();
                        devBox.C_BoxCode = item;
                        devBox.C_DevStoreCode = content.C_DevCode;
                        devBox.C_CreateBy = _claims.ApiUserId.ToString();
                        devBox.D_CreateOn = DateTime.Now;
                        devBox.C_Creator = _claims.ApiUserName;
                        _devBoxRepository.Create(devBox);
                    }
                    var devBoxResult = await _devBoxRepository.SaveAsync();
                }
            }
            else
            {
                throw new Exception("更新失败");
            }
        }
        public async Task UpdateSortAsync(IEnumerable<string> ids)
        {
            int index = 0;
            foreach (var code in ids)
            {
                ++index;
                var items = await _repository.GetByConditionAsync(C => C.C_ID == code);
                var content = items.FirstOrDefault();
                if (content == null)
                {
                    continue;
                }
                content.I_Sort = index;
                _repository.Update(content);
                var result = await _repository.SaveAsync();
            }
        }

        public async Task<bool> devBoxIsExist(TdevWebScadaDevSpotIsExist model)
        {
            bool result = false;
            if (model!=null)
            {
                var items = await _repository.GetByConditionAsync(C => C.C_BoxSpot == model.C_BoxSpot && C.C_GroupName == model.C_GroupName && C.C_BoxNo == model.C_BoxNo);
                if (!string.IsNullOrEmpty(model.C_ID))
                {
                    items = items.Where(t => t.C_ID != model.C_ID).ToList();
                }
                if (items.Count()>0&& items.FirstOrDefault()!=null)
                {
                    result = true;
                }
            }
            return result;
        }

        public async Task<IEnumerable<DevBoxViewModel>> GetdevDevBoxConditionAsync(DevBoxSearchModel searchModel)
        {
            IEnumerable<DevBoxViewModel> list = await _devBoxRepository.GetConditionAsync(searchModel);
            return list;
        }

        public Task<int> UpdateOneAsync(TdevWebScadaDevSpotViewModel viewModel, params string[] fields)
        {
            throw new NotImplementedException();
        }

        public Task<bool> IsExistAsync(string id)
        {
            throw new NotImplementedException();
        }

        public Task<IEnumerable<TdevWebScadaDevSpotViewModel>> GetByConditionAsync(Expression<Func<TdevWebScadaDevSpotViewModel, bool>> expression)
        {
            throw new NotImplementedException();
        }

        public Task UpdateAsync(string code, TpntAreaUpdateModel updateModel)
        {
            throw new NotImplementedException();
        }

        public Task<IEnumerable<TdevWebScadaDevSpotViewModel>> GetConditionAsync(TpntAreaSearchModel searchModel)
        {
            throw new NotImplementedException();
        }

        public Task CreateOneAsync(TdevWebScadaDevSpotViewModel viewModel)
        {
            throw new NotImplementedException();
        }
    }
}