using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCNC.Result;
using Siger.ApiCommon;
using Siger.Middlelayer.CncRepository.Entities;
using Siger.Middlelayer.CncRepository.Repositories.Interface;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Dapper.ResultData;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Redis.Repositories;
using Siger.Middlelayer.Repository.Repositories.Interface;

namespace Siger.ApiCNC.Controllers
{
    public class ParameterMonitorController : BaseController
    {
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly IMachineParamAlarmRepository _machineParamAlarmRepository;
        public ParameterMonitorController(ISigerProjectMachineRepository machineRepository, IMachineParamAlarmRepository machineParamAlarmRepository)
        {
            _machineRepository = machineRepository;
            _machineParamAlarmRepository = machineParamAlarmRepository;
        }

        [HttpGet]
        public IActionResult GetAbnormalDetail()
        {
            var result = new AbnormalDetailResult();

            var machines = _machineRepository.GetList(q => q.projectid == ProjectId && q.status == (int) RowState.Valid && q.category == (int)MachineCategory.NC);
            var machineIds = machines.Select(m => m.id).ToList();
            //只取正在运行的设备
            var machineRepository = new CNCEquipmentStateRepository(CompanyId, ProjectId);
            var states = machineRepository.GetCNCEquipmentStates(machines.Select(m => m.id));
            var validMachines = new List<int>();
            foreach (var state in states)
            {
                if (state.Status >= 1)
                {
                    if (DateTime.Now.Subtract(DateTime.Parse(state.LastUpdateTime)).TotalMinutes <= 5)
                    {
                        validMachines.Add(state.MachineId);
                    }
                }
            }
            result.machine_nums = validMachines.Count;
            if (result.machine_nums == 0)
            {
                //主轴转速异常
                result.data.pieChart.Add(new NameValue
                {
                    name = "800260",
                    value = 0
                });
                //主轴倍率异常
                result.data.pieChart.Add(new NameValue
                {
                    name = "800261",
                    value = 0
                });
                //进给倍率异常
                result.data.pieChart.Add(new NameValue
                {
                    name = "800262",
                    value = 0
                });
                return result;
            }
            IEnumerable<CncExceptionParamsSate> exceptions = null;
            try
            {
                var cncExceptionRepository = new ExceptionParamsSateRepository(CompanyId, ProjectId);
                exceptions = cncExceptionRepository.GetCncExceptionParamsSates(validMachines);
            }
            catch(Exception e)
            {
                Logger.WriteLineError("get CncExceptionParamsSate failed, error:" + e);
                return new ObjectResult(CommonEnum.Fail);
            }
            
            var sates = exceptions.ToList();
            var exceptionMachines = sates.Select(m => m.MachineID).Distinct().ToList();
            foreach (var machine in machines)
            {
                if (exceptionMachines.Contains(machine.id))
                {
                    result.data.exceptionCount++;
                }
                else
                {
                    result.data.normalCount++;
                }
            }
            result.data.pieChart.Add(new NameValue
            {
                name = "800260",
                value = sates.Count(q => q.Type == 1)
            });
            result.data.pieChart.Add(new NameValue
            {
                name = "800261",
                value = sates.Count(q => q.Type == 2)
            });
            result.data.pieChart.Add(new NameValue
            {
                name = "800262",
                value = sates.Count(q => q.Type == 3)
            });
            var stations = _machineRepository.GetNCMachinSectionInfos(machineIds, ProjectId).ToList();
            //取配置的上下限
            var machineAlarms = _machineParamAlarmRepository.GetList(q =>
                machineIds.Contains(q.machine_id) && q.project_id == ProjectId
                                                                  && q.status == (int) RowState.Valid).ToList();

            var stationIds = stations.Select(m => m.id).Distinct();
            foreach (var stationId in stationIds)
            {
                var station = stations.FirstOrDefault(q => q.id == stationId);
                if (station == null)
                {
                    continue;
                }

                var list = new List<AbnormalDetailInfo>();
                var stationMachineIds = stations.Where(m => m.id == station.id).Select(m => m.machineId);

                var excep = exceptions.Where(q => stationMachineIds.Contains(q.MachineID));
                foreach (var exception in excep)
                {
                    var rowCount = excep.Count();
                    var firstRow = list.Select(m => m.section_id).Contains(station.id) == false;
                    var alarm = machineAlarms.FirstOrDefault(m => m.machine_id == exception.MachineID);

                    var machineStation = stations.FirstOrDefault(q => q.machineId == exception.MachineID);
                    if (machineStation == null)
                    {
                        continue;
                    }

                    var paramters = GetUpDownLimit(alarm, exception.Type);
                    var entity = new AbnormalDetailInfo
                    {
                        values = exception.Values,
                        downlimit = paramters[0],
                        exception_type = exception.Type,
                        StartTime = exception.StartTime.ToString(ParameterConstant.DateTimeFormat),
                        uplimit = paramters[1],
                        //TimeSpan = UnixTimeHelper.GetTimeBySecond(exception.TotalSecond),
                        TimeSpan = exception.TotalSecond.ToString(),
                        row_count = firstRow ? rowCount : 0,
                        section_id = machineStation.id,
                        station_name = machineStation.station_name,
                        section_name = machineStation.section_name,
                        endOf = exception.Closed.ToString()
                    };
                    list.Add(entity);
                    result.data.ProductionParameterLis[station.id] = list;
                }
            }
            
            return result;
        }

        private List<string> GetUpDownLimit(siger_project_machine_param_alarm alarm, int parameterType)
        {
            var downLimit = "-1";
            var upLimit = "-1";
            if (alarm != null)
            {
                switch (parameterType)
                {
                    case (int)ParameterType.AxisSpeed:
                        downLimit = alarm.axis_speed_low;
                        upLimit = alarm.axis_speed_top;
                        break;
                    case (int)ParameterType.AxisRate:
                        downLimit = alarm.axis_rate_low;
                        upLimit = alarm.axis_rate_top;
                        break;
                    case (int)ParameterType.FeedRate:
                        downLimit = alarm.feed_rate_low;
                        upLimit = alarm.feed_rate_top;
                        break;
                }
            }

            return new List<string>
            {
                downLimit == "-1" ? "NA" : downLimit,
                upLimit == "-1" ? "NA" : upLimit
            };
        }

    }
}