using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCNC.Result;
using Siger.ApiCommon.Filters;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Redis.RedisEntities;
using Siger.Middlelayer.Redis.Repositories;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Share.Models;

namespace Siger.ApiCNC.Controllers
{
    [Route("cnc/[controller]/[action]")]
    [ApiController]
    public class LidaApiController : ControllerBase
    {
        private const int Cid = 108;
        private const int Pid = 125;

        private readonly ISigerProjectMachineRepository _machineRunningRepository;
        public LidaApiController(ISigerProjectMachineRepository machineRunningRepository)
        {
            _machineRunningRepository = machineRunningRepository;
        }

        /// <summary>
        /// for lida
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [NoTokenValidateFilter]
        public async Task<IActionResult> GetMachineTotalStatus()
        {
            return await Task.Run(() =>
            {
                var validMachines = _machineRunningRepository.GetNCLevelSectionMachines(0, Pid);
                var machineDatas = validMachines.ToList();
                
                var dic = new Dictionary<string, int>();
                var result = new MachineRunningResult();
                try
                {
                    var machineIds = machineDatas.Select(m => m.machine_id);
                    var redisRepository = new CNCEquipmentStateRepository(Cid, Pid);
                    var machineStates = redisRepository.GetCNCEquipmentStates(machineIds);
                    foreach (var machine in machineDatas)
                    {
                        var status = 0;
                        var machineState = machineStates.FirstOrDefault(q => q.MachineId == machine.machine_id);
                        if (machineState != null)
                        {
                            if (DateTime.Now.Subtract(DateTime.Parse(machineState.LastUpdateTime)).TotalMinutes <=
                                CommonConst.MachineShutDownThreshold)
                            {
                                status = machineState.Status;
                            }
                        }

                        if (status == (int)MachineRunningStatus.Running)
                        {
                            result.running++;
                        }

                        if (status == (int)MachineRunningStatus.Debugging)
                        {
                            result.debugging++;
                        }

                        if (status == (int)MachineRunningStatus.Free)
                        {
                            result.idle++;
                        }

                        if (status == (int)MachineRunningStatus.Fault)
                        {
                            result.fault++;
                        }
                        else //关机
                        {
                            result.shutdown++;
                        }
                    }

                    dic.Add("运行", result.running);
                    dic.Add("调试", result.debugging);
                    dic.Add("空闲", result.idle);
                    dic.Add("报警", result.fault);
                    dic.Add("关机", result.shutdown);
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("GetMachineTotalStatus failed, error :" + e);
                    dic.Add("运行", 0);
                    dic.Add("调试", 0);
                    dic.Add("空闲", 0);
                    dic.Add("报警", 0);
                    dic.Add("关机", machineDatas.Count);
                }

                return new ObjectResult(dic);
            });
        }

        [HttpGet]
        [NoTokenValidateFilter]
        public async Task<IActionResult> GetMachineDetailState()
        {
            return await Task.Run(() =>
            {
                var validMachines = _machineRunningRepository.GetNCLevelSectionNames(0, Pid);
                var machineDatas = validMachines.ToList();
                if (!machineDatas.Any())
                {
                    throw new BadRequestException(RequestEnum.MachineNotFound);
                }

                var responses = new List<MachineDetailState>();
                try
                {
                    var machineIds = machineDatas.Select(m => m.machine_id);
                    var redisRepository = new CNCEquipmentStateRepository(Cid, Pid);
                    var machineStates = redisRepository.GetCNCEquipmentStates(machineIds);

                    var dieRep = new CNCPressureTemperatureRepository(Cid, Pid);
                    var dieMachineStates = dieRep.GetCncPressureTemperatures(machineIds);
                    foreach (var machine in machineDatas)
                    {
                        var status = 0;
                        var response = new MachineDetailState
                        {
                            location = machine.lastSecondSectionTitle,
                            machineCode = machine.machine_code,
                            machineName = machine.machine_name,
                            feedRatio = 0,
                            spindleRatio = 0,
                            spindleSpeed = 0,
                            programNo = "",
                            state = "关机",
                            pressure = 0,
                            temperature = 0,
                        };

                        var machineState = machineStates.FirstOrDefault(q => q.MachineId == machine.machine_id);
                        if (machineState != null)
                        {
                            if (DateTime.Now.Subtract(DateTime.Parse(machineState.LastUpdateTime)).TotalMinutes <=
                                CommonConst.MachineShutDownThreshold)
                            {
                                status = machineState.Status;
                            }
                            var machineReturn = Mapper<CNCEquipmentState, MachineState>.Map(machineState);
                            response.feedRatio = machineReturn.FeedRatio;
                            response.spindleRatio = machineReturn.SpindleRatio;
                            response.spindleSpeed = machineReturn.SpindleSpeed1;
                            response.programNo = machineReturn.PN;
                            response.state = EnumHelper.GetEnumDesc((MachineRunningStatus)status);
                        }
                        else
                        {
                            var dieMachine = dieMachineStates.FirstOrDefault(q => q.mn == machine.machine_id);
                            if (dieMachine != null)
                            {
                                if (dieMachine.opm == 1)//1：运行 2: 调试 3：关机
                                {
                                    response.state = EnumHelper.GetEnumDesc(MachineRunningStatus.Running);
                                }
                                if (dieMachine.opm == 2)
                                {
                                    response.state = EnumHelper.GetEnumDesc(MachineRunningStatus.Debugging);
                                }
                                else
                                {
                                    response.state = EnumHelper.GetEnumDesc(MachineRunningStatus.Shutdown);
                                }
                                response.pressure = dieMachine.pressure.ToDouble();
                                response.temperature = dieMachine.temperature.ToDouble();
                            }
                        }

                        responses.Add(response);
                    }
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("GetMachineDetailState failed, error :" + e);
                }

                return new ObjectResult(responses);
            });
        }
    }
}