using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.ApiDNC.Utility;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.DncRepository.Repositories.Interface;
using Siger.Middlelayer.DncRepository.Response;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Utility.Helpers;

namespace Siger.ApiDNC.Controllers
{
    public class DncContrastController : BaseController
    {
        private readonly ISigerProjectDncProgramRepository _sigerProjectDncProgramRepository;
        private readonly ISigerDncJobProgramRepository _dncJobProgramRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;

        public DncContrastController(ISigerProjectDncProgramRepository sigerProjectDncProgramRepository, ISigerDncJobProgramRepository dncJobProgramRepository,
            ISigerProjectMachineRepository machineRepository)
        {
            _sigerProjectDncProgramRepository = sigerProjectDncProgramRepository;
            _dncJobProgramRepository = dncJobProgramRepository;
            _machineRepository = machineRepository;
        }

        /// <summary>
        /// DNC程序对比管理>程序对比->获取已审核数据
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetCheckedList(string keyword,int page, int pageSize)
        {
            var result = _sigerProjectDncProgramRepository.GetAllProgarm(ProjectId, keyword, (int)CheckState.Checked,page,pageSize,out int totalCount);
            return new PagedObjectResult(result,totalCount,page,pageSize);
        }
        /// <summary>
        /// 修改记录
        /// </summary>
        /// <param name="sectionid"></param>
        /// <param name="programcode"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetProgramHistory(int sectionid,string programcode,[Required(ErrorMessage= "StartTimeNotNull")]DateTime starttime, 
                                                [Required(ErrorMessage = "EndTimeNotNull")]DateTime endtime,int page=1,int pagesize=10)
        {
            return GetPgMonitorlists(sectionid, programcode, starttime, ref endtime, page, pagesize, ChangeProgramType.Update);
        }

        private IActionResult GetPgMonitorlists(int sectionid, string programcode, DateTime starttime, ref DateTime endtime, int page, int pagesize, ChangeProgramType? type=null)
        {
            if (endtime != null)
            {
                endtime = endtime.Date.AddDays(1);
            }
            var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, sectionid);
            if(type==null)
            {
                CheckMachine(machine.id);
            }
            var changeProgram = _dncJobProgramRepository.GetChangeProram(machine.id, programcode, starttime, endtime, type, ProjectId, page, pagesize);
            if (changeProgram?.ListDetails != null)
            {
                foreach (var item in changeProgram.ListDetails)
                {
                    item.machine_id = machine.id;
                    item.machine_name = machine.title;
                    //获取程序号的产品信息
                    var info = _sigerProjectDncProgramRepository.GetProgramCheckedInfo(ProjectId, item.program_number);
                    if (info != null)
                    {
                        item.productname = string.IsNullOrEmpty(info.productname) ? "NA" : info.productname;
                        item.productcode = string.IsNullOrEmpty(info.productcode) ? "NA" : info.productcode;
                    }
                    else
                    {
                        item.productname = "NA";
                        item.productcode = "NA";
                    }
                }
            }
           
            return new PagedObjectResult(changeProgram.ListDetails, changeProgram.TotalCount,page,pagesize);
        }

        /// <summary>
        /// 获取程序上传记录
        /// </summary>
        /// <param name="sectionid"></param>
        /// <param name="programcode"></param>
        /// <param name="type"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetPgMonitorlists(int sectionid, string programcode, DateTime starttime, DateTime endtime, int type , int page = 1, int pagesize = 10)
        {
            ChangeProgramType? typeValue;
            if (type == 0)
                typeValue = null;
            else
                typeValue = (ChangeProgramType)type;
            return GetPgMonitorlists(sectionid, programcode, starttime, ref endtime, page, pagesize, typeValue);
        }

        [HttpGet]
        public IActionResult GetPgStatisticlists(int sectionid, int type1, int type2, string type3, DateTime starttime, DateTime endtime)
        {
            if (endtime != null)
            {
                endtime = endtime.Date.AddDays(1);
            }
            var machineIdList = _machineRepository.GetNCLevelSectionMachineIds(sectionid, ProjectId).ToList();
            if (!machineIdList.Any())
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }
            //程序上传至nc次数
            if (1 == type1)
            {
                //时间范围
                if (1 == type2)
                {
                    var result = new ResponsePgStatisticlists();
                    var region = _sigerProjectDncProgramRepository.GetRegion(sectionid, ProjectId);
                    int span = 24 * 3600;
                    switch (type3)
                    {
                        case "day":
                            break;
                        case "week":
                            {
                                span *= 7;
                            }
                            break;
                        case "month":
                            {
                                span *= 7 * 30;
                            }
                            break;
                        default:
                            throw new BadRequestException(RequestEnum.ParameterError);
                    }

                    if (type3== "week")
                    {
                        var st = starttime;
                        var et = starttime;
                        while (st < endtime)
                        {
                            var xData = DateTimeHelper.GetStrDateTimes(et, et.AddDays(1).AddSeconds(-1), 11);
                            var weekStart = DateTimeHelper.GetWeekRangeStart(xData[0]);
                            var weekEnd = DateTimeHelper.GetWeekRangeEnd(xData[0]);
                            st = starttime > weekStart ? starttime : weekStart;
                            et = endtime < weekEnd ? endtime : weekEnd.AddDays(1);
                            int num = _sigerProjectDncProgramRepository.GetPgUploadCount(machineIdList, st, et);
                            var time = xData[0];
                            result.arr.Add(new PgStatisticlistsData
                            {
                                datetime=time,
                                region = region,
                                num = num
                            });
                            st= et;
                            result.data.datetime.Add(time);
                            result.data.num.Add(num);
                        }
                    }else if (type3 == "month")
                    {
                        var st = starttime;
                        var et = starttime;
                        var xData = DateTimeHelper.GetStrDateTimes(starttime, endtime.AddSeconds(-1), 12);
                        var dates = DateTimeHelper.GetDateTimes(starttime, endtime.AddSeconds(-1), 12);
                        var count = 0;
                        while (st < endtime)
                        {

                            st = dates[count];
                            var dts = st.AddMonths(1);
                            dts = dts.AddDays(0 - dts.Day).AddDays(1).AddSeconds(-1);
                            et = dts > endtime ? endtime.AddSeconds(-1) : dts; //到月底
                            int num = _sigerProjectDncProgramRepository.GetPgUploadCount(machineIdList, st, et);
                            var time = et.ToString("yyyy-MM"); ;
                            result.arr.Add(new PgStatisticlistsData
                            {
                                datetime = time,
                                region = region,
                                num = num
                            });
                            st = et.AddSeconds(1);
                            result.data.datetime.Add(time);
                            result.data.num.Add(num);
                            count++;
                        }
                    }
                    else
                    {
                        var st = starttime;
                        var et = st.AddSeconds(span)> endtime? endtime: st.AddSeconds(span);
                        while (st < endtime)
                        {
                            //get
                            int num = _sigerProjectDncProgramRepository.GetPgUploadCount(machineIdList, st, et);
                            var time = st.ToString("yyyy-MM-dd");
                            result.arr.Add(new PgStatisticlistsData
                            {
                                datetime = time,
                                region = region,
                                num = num
                            });
                            result.data.datetime.Add(time);
                            result.data.num.Add(num);
                            st = et;
                            et = et.AddSeconds(span);
                        }
                        if (!result.arr.Any())
                            throw new BadRequestException(CommonEnum.RecordNotFound);
                    }
                   
                    return new ObjectResult(result);
                }
                //产线层级
                else if (2 == type2)
                {
                    var result = new ResponseListByLevels();
                    if ( !string.IsNullOrEmpty(type3))
                    {
                        int.TryParse(type3, out int levelid);
                        var sectionIds = _machineRepository.GetNCLevelSections(sectionid, ProjectId).Select(m => m.id).ToList();
                        var data=_sigerProjectDncProgramRepository.GetLevels(levelid, ProjectId);
                        int total = 0;
                        foreach (var item in data)
                        {
                            //根据产线层级获取设备id
                            if (!sectionIds.Contains(item.id))
                            {
                                continue;
                            }
                            var mids = _machineRepository.GetNCLevelSectionMachineIds(item.id, ProjectId).ToList();
                            var num = _sigerProjectDncProgramRepository.GetPgUploadCount(mids,starttime,endtime);
                            var tmp = new arr
                            {
                                title = item.title,
                                num= num
                            };
                            result.arr.Add(tmp);
                            total += num;
                        }
                        if(result.arr.Any())
                        {
                            result.arr.Sort();
                            int count = 0;
                            foreach (var item in result.arr)
                            {
                                count+=item.num;
                                var beifen = total!=0 ? Math.Round((double)(count / total * 100), 2) : 0;
                                result.data.title.Add(item.title);
                                result.data.num1.Add(item.num);
                                result.data.num2.Add(beifen);
                            }
                        }
                    }
                    //选择的是最后一级,工位
                    else
                    {
                        var mids = _machineRepository.GetNCLevelSectionMachineIds(sectionid, ProjectId).ToList();
                        var region = _sigerProjectDncProgramRepository.GetRegion(sectionid, ProjectId);
                        var num = _sigerProjectDncProgramRepository.GetPgUploadCount(mids, starttime, endtime);
                        var total = num;
                        result.arr.Add(new arr
                        {
                            title = region,
                            num = num
                        });
                        var beifen = total != 0 ? Math.Round((double)num / total * 100, 2) : 0;
                        result.data.title.Add(region);
                        result.data.num1.Add(num);
                        result.data.num2.Add(beifen);
                    }
                    return new ObjectResult(result);
                }
                else if (3 == type2)//人员（人员分为创建人及审核人）
                {
                    //获取上传次数,$type3 = 1时是创建人，2是审核人
                    var arr = _sigerProjectDncProgramRepository.GetPgUploadCountBymid(machineIdList,type3,starttime,endtime,ProjectId);
                    arr.Sort();
                    int total = 0;
                    var result = new ResponseListByLevels();
                    foreach (var item in arr)
                    {
                        total += item.num;
                        result.arr.Add(new arr
                        {
                            num= item.num,
                            title=item.NAME
                        });
                    }
                    int count = 0;
                    foreach (var item in arr)
                    {
                        count += item.num;
                        var beifen = total != 0 ? Math.Round((double)count / total * 100, 2) : 0;
                        result.data.title.Add(item.NAME);
                        result.data.num1.Add(item.num);
                        result.data.num2.Add(beifen);
                    }
                    return new ObjectResult(result);
                }
                //产品名称
                else
                {
                    var result = new ResponseListByLevels();
                    var arr=_sigerProjectDncProgramRepository.GetPgUploadCountByProduct(machineIdList,starttime,endtime,ProjectId);
                    if(arr.Any())
                    {
                        arr.Sort();
                        int total = 0;
                        foreach (var item in arr)
                        {
                            total += item.num;
                            result.arr.Add(new arr
                            {
                                num=item.num,
                                title=item.NAME
                            });
                        }

                        int count = 0;
                        foreach (var item in arr)
                        {
                            count += item.num;
                            var beifen = total != 0 ? Math.Round((double)count/total*100,2) : 0;
                            result.data.title.Add(item.NAME);
                            result.data.num1.Add(item.num);
                            result.data.num2.Add(beifen);
                        }
                    }
                    return new ObjectResult(result);
                }
            }
            //nc端程序修改次数
            else
            {
                //时间范围
                if (1 == type2)
                {
                    //根据sectionid获取区域信息
                    var region = _sigerProjectDncProgramRepository.GetRegion(sectionid, ProjectId);
                    var result = new ResponsePgStatisticlists();
                    int span = 24 * 3600;
                    switch (type3)
                    {
                        case "day":
                            break;
                        case "week":
                            {
                                span *= 7;
                            }
                            break;
                        case "month":
                            {
                                span *= 7 * 30;
                            }
                            break;
                        default:
                            throw new BadRequestException(RequestEnum.ParameterError);
                    }
                    if (type3 == "week")
                    {
                        var st = starttime;
                        var et = starttime;
                        while (st < endtime)
                        {
                            var xData = DateTimeHelper.GetStrDateTimes(et, et.AddDays(1).AddSeconds(-1), 1);
                            var weekStart = DateTimeHelper.GetWeekRangeStart(xData[0]);
                            var weekEnd = DateTimeHelper.GetWeekRangeEnd(xData[0]);
                            st = starttime > weekStart ? starttime : weekStart;
                            et = endtime < weekEnd ? endtime : weekEnd.AddDays(1);
                            int num = _dncJobProgramRepository.GetChangeCount(machineIdList, st, et, ProjectId);
                            var time = xData[0];
                            result.arr.Add(new PgStatisticlistsData
                            {
                                datetime = time,
                                region = region,
                                num = num
                            });
                            st = et;
                            result.data.datetime.Add(time);
                            result.data.num.Add(num);
                        }
                    }
                    else
                    {
                        var st = starttime;
                        var et = st.AddSeconds(span) > endtime ? endtime : st.AddSeconds(span);
                        while (st < endtime)
                        {
                            //get
                            int num = _dncJobProgramRepository.GetChangeCount(machineIdList, st, et, ProjectId);
                            var time = st.ToString("yyyy-MM-dd");
                            result.arr.Add(new PgStatisticlistsData
                            {
                                datetime = time,
                                region = region,
                                num = num
                            });
                            result.data.datetime.Add(time);
                            result.data.num.Add(num);
                            st = et;
                            et = et.AddSeconds(span);
                        }
                        if (!result.arr.Any())
                            throw new BadRequestException(CommonEnum.RecordNotFound);
                    }

                    return new ObjectResult(result);
                }
                //产线层级
                else if (2 == type2)
                {
                    var result = new ResponseListByLevels();
                    if (!string.IsNullOrEmpty(type3))
                    {
                        int.TryParse(type3,out int type3Value);
                        var sectionIds = _machineRepository.GetNCLevelSections(sectionid, ProjectId).Select(m => m.id).ToList();
                        var levels=_sigerProjectDncProgramRepository.GetLevels(type3Value, ProjectId);
                        int total = 0;
                        foreach (var item in levels)
                        {
                            var machineIdLists = _machineRepository.GetNCLevelSectionMachineIds(item.id, ProjectId).ToList();
                            //根据产线层级获取设备id
                            if (!sectionIds.Contains(item.id))
                            {
                                continue;
                            }
                            var num = _dncJobProgramRepository.GetChangeCount(machineIdLists, starttime, endtime, ProjectId);
                            var tmp = new arr
                            {
                                title = item.title,
                                num = num
                            };
                            result.arr.Add(tmp);
                            total += num;

                        }
                        if (result.arr.Any())
                        {
                            result.arr.Sort();
                            int count = 0;
                            foreach (var item in result.arr)
                            {
                                count += item.num;
                                var beifen = total != 0 ? Math.Round((double)(count / total * 100), 2) : 0;
                                result.data.title.Add(item.title);
                                result.data.num1.Add(item.num);
                                result.data.num2.Add(beifen);
                            }
                        }
                    }
                    //选择的是最后一级,工位
                    else
                    {
                        var region = _sigerProjectDncProgramRepository.GetRegion(sectionid, ProjectId);
                        var num = _dncJobProgramRepository.GetChangeCount(machineIdList, starttime, endtime, ProjectId);
                        var total = num;
                        result.arr.Add(new arr
                        {
                            title = region,
                            num = num
                        });
                        var beifen = total != 0 ? Math.Round((double)num / total * 100, 2) : 0;
                        result.data.title.Add(region);
                        result.data.num1.Add(num);
                        result.data.num2.Add(beifen);
                    }
                    return new ObjectResult(result);
                }
                //人员
                else if (3 == type2)
                {
                    //获取上传次数,$type3 = 1时是创建人，2是审核人
                    var arr = _sigerProjectDncProgramRepository.GetPgHistoryCountBymid(CompanyId,ProjectId,machineIdList, type3, starttime, endtime, ProjectId);
                    arr.Sort();
                    int total = 0;
                    var result = new ResponseListByLevels();
                    foreach (var item in arr)
                    {
                        total += item.num;
                        result.arr.Add(new arr
                        {
                            num = item.num,
                            title = item.name
                        });
                    }
                    int count = 0;
                    foreach (var item in arr)
                    {
                        count += item.num;
                        var beifen = total != 0 ? Math.Round((double)count / total * 100, 2) : 0;
                        result.data.title.Add(item.name);
                        result.data.num1.Add(item.num);
                        result.data.num2.Add(beifen);
                    }
                    return new ObjectResult(result);
                }
                //产品名称
                else
                {
                    var result = new ResponseListByLevels();
                    var arr = _sigerProjectDncProgramRepository.GetPgHistoryCountByProduct(CompanyId,ProjectId,machineIdList, starttime, endtime, ProjectId);
                    if (arr.Any())
                    {
                        arr.Sort();
                        int total = 0;
                        foreach (var item in arr)
                        {
                            total += item.num;
                            result.arr.Add(new arr
                            {
                                num = item.num,
                                title = item.name
                            });
                        }

                        int count = 0;
                        foreach (var item in arr)
                        {
                            count += item.num;
                            var beifen = total != 0 ? Math.Round((double)count / total * 100, 2) : 0;
                            result.data.title.Add(item.name);
                            result.data.num1.Add(item.num);
                            result.data.num2.Add(beifen);
                        }
                    }
                    return new ObjectResult(result);
                }
            }
        }
       
        [HttpGet]
        public IActionResult GetProgramBymID(int sectionid,int page = 1,int pageSize = 10)
        {
            var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, sectionid);
            CheckMachines(machine.id);
            var para = new List<KeyValuePair<string, string>>
            {
                new KeyValuePair<string, string>("machineName", machine.id.ToString())
            };

            try
            {
                var pros = DNCHttpUtility.GetProgramList(CompanyId, ProjectId, para); //from 数采

                var programs = _sigerProjectDncProgramRepository.GetCheckProgramDeleteList(pros);

                var jobPrograms = _dncJobProgramRepository.GetList(q => q.machine_name == machine.id.ToString() && q.projectid == ProjectId).ToList();

                var updatedPrograms = GetUpdatedPrograms(jobPrograms, pros);
                var data = ClcaProgramInfo(machine, pros, programs, updatedPrograms);
                var totalCount = data.Count();
                data =data.Skip((page - 1) * pageSize).Take(pageSize).ToList();
                return new PagedObjectResult(data, totalCount,page,pageSize);
            }
            catch (Exception e)
            {
                Logger.WriteLineError("GetProgramBymID failed, error: " + e);
                throw new BadRequestException(RequestEnum.CallInterfaceError);
            }
        }
        private void CheckMachines(int machineid)
        {
            var attribute = _sigerProjectDncProgramRepository.GetMachineAttribute(machineid);
            if (attribute == MachineAttributeType.Serialport || attribute == MachineAttributeType.NoneSystem)
                throw new BadRequestException(RequestEnum.DncCallMachineIsNotFunction);
        }
        private void CheckMachine(int machineid)
        {
            var attribute = _sigerProjectDncProgramRepository.GetMachineAttribute(machineid);
            if (attribute == MachineAttributeType.Serialport || attribute == MachineAttributeType.NoneSystem)
                throw new BadRequestException(RequestEnum.DeviceNotSupport);
        }
    }
}