using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Siger.ApiCommon.Filters;
using Siger.ApiCommon.Result;
using Siger.ApiDNC.Utility;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.DncRepository.Entities;
using Siger.Middlelayer.DncRepository.Repositories.Interface;
using Siger.Middlelayer.DncRepository.Request;
using Siger.Middlelayer.DncRepository.Response;
using Siger.Middlelayer.Redis;

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

        public DncUpDownController(ISigerProjectDncProgramRepository sigerProjectDncProgramRepository, ISigerDncJobProgramRepository dncJobProgramRepository)
        {
            _sigerProjectDncProgramRepository = sigerProjectDncProgramRepository;
            _dncJobProgramRepository = dncJobProgramRepository;
        }

        /// <summary>
        /// 验证程序号--是否有重复程序号且未审核的程序
        /// </summary>
        /// <param name="programcode"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Checkprograms(string programcode)
        {
            var list = _sigerProjectDncProgramRepository.GetList(f => f.checkstatus == (int)CheckState.Waiting && f.program_code == programcode && f.status == (int)RowState.Valid);
            if (!list.Any())
                return new InformationResult(0);
            return new ObjectResult(list);
        }

        /// <summary>
        /// 验证程序号--是否有重复程序号且未审核的程序CL
        /// </summary>
        /// <param name="programcode"></param>
        /// <param name="programId"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult CheckprogramsNew(string programcode,int programId)
        {
            var list = _sigerProjectDncProgramRepository.GetList(f => f.checkstatus == (int)CheckState.Waiting && f.program_code == programcode && f.status == (int)RowState.Valid && f.id != programId);
            if (!list.Any())
                return new InformationResult(0);
            return new ObjectResult(list);
        }

        /// <summary>
        /// 获取程序上传记录
        /// </summary>
        /// <param name="sectionid"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetPguploadlists(int sectionid, DateTime starttime, DateTime endtime, int page = 1, int pagesize = 10)
        {
            var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, sectionid);
           
            if (machine == null)
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }
            var data = _sigerProjectDncProgramRepository.GetPguploadlists(machine, starttime, endtime.Date.AddDays(1), page, pagesize);
            return new PagedObjectResult(data.Data, data.Total, page, pagesize);
        }

        /// <summary>
        /// 获取已审核程序号
        /// </summary>
        /// <param name="product"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetPrograms(string product,int page,int pagesize)
        {
            var data = _sigerProjectDncProgramRepository.SearchProgramEx(ProjectId, product, (int)CheckState.Checked,page, pagesize);
            var result = data.Data.ToList();
            foreach (var item in result)
            {
                item.file_size = FileUtility.GetFileSize(item.file_size.ToInt());
                item.program_code = HttpUtility.HtmlDecode(item.program_code);
            }
            return new PagedObjectResult(result, data.Total, page, pagesize);
        }

        [HttpPost]
        public IActionResult UploadProgramPost([FromBody]RequesetUploadProgramPost req)
        {
            var machineId = req.machineid;
            if (req.sectionid != 0)
            {
                var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, req.sectionid);
                machineId = machine.id;
            }

            var programinfo = _sigerProjectDncProgramRepository.GetProgramInfo(ProjectId, req.programid);
            if (programinfo==null)
            {
                Logger.WriteLineInfo($"program id {req.programid} not found ");
                throw new BadRequestException(RequestEnum.RecordNull);
            }
            if (programinfo.file_name.Contains(".zip", StringComparison.InvariantCultureIgnoreCase) 
                || programinfo.file_name.Contains(".jpg", StringComparison.InvariantCultureIgnoreCase)
                || programinfo.file_name.Contains(".eng", StringComparison.InvariantCultureIgnoreCase)
                || programinfo.file_name.Contains(".dwg", StringComparison.InvariantCultureIgnoreCase))
            {
                var data = _sigerProjectDncProgramRepository.UploadProgramZip(ProjectId, UserId, machineId, req.programid, programinfo);
                return UploadZipProgram(data, programinfo.program_code);
            }
            else
            {
                var data = _sigerProjectDncProgramRepository.UploadProgram(ProjectId, UserId, machineId, req.programid, programinfo, out string param);
                return UploadProgram(data, param);
                
            }
        }
        /// <summary>
        /// 上传主程序以及主程序下的子程序
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UploadMainSonProgram([FromBody] RequesetUploadProgramPost req)
        {
            var machineId = req.machineid;
            if (req.sectionid != 0)
            {
                var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, req.sectionid);
                machineId = machine.id;
            }

            var programinfo = _sigerProjectDncProgramRepository.GetProgramInfoById(ProjectId, req.programid);
            foreach (var item in programinfo)
            {
                Logger.WriteLineInfo($"item :{item.program_code }");
                var sonProgram = _sigerProjectDncProgramRepository.GetListByGuidCode(item.guidcode, ProjectId, item.productcode);
                foreach (var son in sonProgram)
                {
                    if (string.IsNullOrEmpty(son.program_code))
                        continue;
                    //Logger.WriteLineInfo($"son :{son.program_code }");
                    //if (son.file_name.Contains(".zip", StringComparison.InvariantCultureIgnoreCase)
                    //     || son.file_name.Contains(".jpg", StringComparison.InvariantCultureIgnoreCase)
                    //     || son.file_name.Contains(".eng", StringComparison.InvariantCultureIgnoreCase)
                    //     || son.file_name.Contains(".dwg", StringComparison.InvariantCultureIgnoreCase))
                    //{
                    //    var dataZip = _sigerProjectDncProgramRepository.UploadProgramZip(ProjectId, UserId, machineId, req.programid, son);

                    //    UploadZipProgram(dataZip, son.program_code);
                    //}
                    //else
                    //{
                    //    var dataOrdinary = _sigerProjectDncProgramRepository.UploadProgram(ProjectId, UserId, machineId, req.programid, son, out string param);
                    //    UploadProgram(dataOrdinary, param);
                    //}
                    DoUpload(son, machineId, req.programid);

                }
                DoUpload(item, machineId, req.programid);


            }
            return new ObjectResult(CommonEnum.Succefull);
        }
        void DoUpload(ResponseProgramInfo DncProgram,int machineId,int programId)
        {
            if (DncProgram.file_name.Contains(".zip", StringComparison.InvariantCultureIgnoreCase)
                        || DncProgram.file_name.Contains(".jpg", StringComparison.InvariantCultureIgnoreCase)
                        || DncProgram.file_name.Contains(".eng", StringComparison.InvariantCultureIgnoreCase)
                        || DncProgram.file_name.Contains(".dwg", StringComparison.InvariantCultureIgnoreCase))
            {
                var dataZip = _sigerProjectDncProgramRepository.UploadProgramZip(ProjectId, UserId, machineId, programId, DncProgram);
                UploadZipProgram(dataZip, DncProgram.program_code);
            }
            else
            {
                var dataOrdinary = _sigerProjectDncProgramRepository.UploadProgram(ProjectId, UserId, machineId, programId, DncProgram, out string param);
                UploadProgram(dataOrdinary, param);
            }
        }

        private IActionResult UploadProgram(siger_project_dnc data, string param)
        {
            var dbName = RedisCache.Instance.GetDbName(CompanyId, ProjectId);
            var ip = dbName.SCService;
            var port = dbName.SCPort;

            try
            {
                var ret = HttpHelper.HttpPost($"{ip}:{port}{CommonConst.DownloadProgram}", "application/json", param);
                var result = (ResponseGetNCValue)JsonConvert.DeserializeObject(ret, typeof(ResponseGetNCValue));
                if (result.ret != 0)
                {
                    Logger.WriteLineError($"UploadProgram failed,input:{param } result :{ret}");
                    throw new BadRequestException(RequestEnum.UploadError);
                }

                var buteData = Encoding.Default.GetBytes(data.file_content);
                data.file_content = Convert.ToBase64String(buteData);

                _sigerProjectDncProgramRepository.AddDnc(data);
                return new ObjectResult(CommonEnum.Succefull);
            }
            catch (Exception e)
            {
                Logger.WriteLineError($"UploadProgram failed,input:{param} error: {e}");
                throw new BadRequestException(RequestEnum.UploadError);
            }
        }

        private IActionResult UploadZipProgram(siger_project_dnc data, string programCode)
        {
            var dbName = RedisCache.Instance.GetDbName(CompanyId, ProjectId);
            var ip = dbName.SCService;
            var port = dbName.SCPort;

            var url =  $"{ip}:{port}{CommonConst.DownloadProgramPackage}?machineName={data.machine_id}&programNumber={programCode}";

            var path = FileUtility.GetTruePath(data.file_content);
            if (!System.IO.File.Exists(path))
            {
                throw new BadRequestException(RequestEnum.ErrorFilePath);
            }

            var ret = HttpHelper.HttpPostFile(url, path);
            var result = (ResponseGetNCValue) JsonConvert.DeserializeObject(ret, typeof(ResponseGetNCValue));
            if (result.ret != 0)
            {
                throw new BadRequestException(RequestEnum.UploadError);
            }

            data.file_content = "";
            _sigerProjectDncProgramRepository.AddDnc(data);
            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpGet]
        public IActionResult GetPgDownloadlists(int sectionid, string programcode, int page = 1, int pagesize = 10)
        {
            var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, sectionid);
            
            var para = new List<KeyValuePair<string, string>>();
            para.Add(new KeyValuePair<string, string>("machineName", machine.id.ToString()));
            var pros = DNCHttpUtility.GetProgramList(CompanyId, ProjectId, para);
          
            if (!string.IsNullOrEmpty(programcode))
            {
                pros = pros.Where(f => f.Contains(programcode)).ToList();
            }
            var totalCount = pros.Count;
            //分页
            pros = pros.Skip((page - 1) * pagesize).Take(pagesize).ToList();

            //获取当前页的已审核程序
            var checkProgram = _sigerProjectDncProgramRepository.GetCheckProgram(ProjectId, pros);

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

            var result = ClcaProgramInfo(machine, pros, checkProgram, updatedPrograms);

            //拼接显示数据
            return new PagedObjectResult(result, totalCount, page, pagesize);
        }


        [HttpGet]
        public IActionResult GetProgramContent(int machine_id, string programcode)
        {
            var ret = DNCHttpUtility.GetProgram(CompanyId, ProjectId, machine_id, programcode);

            return new ObjectResult(ret);
        }

        [HttpPost]
        public IActionResult DownloadProgram([FromBody]RequestDownloadProgram req)
        {
            var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, req.sectionid);
            //获取程序后缀名
            var programs = _sigerProjectDncProgramRepository.GetList(q =>
                q.status == (int) RowState.Valid && q.projectid == ProjectId && req.data.Contains(q.program_code)).ToList();

            var dicts = new Dictionary<string, string>();
            foreach (var program in req.data)
            {
                var extion = "txt";
                var pro = programs.FirstOrDefault(q => q.program_code == program);
                if (!string.IsNullOrWhiteSpace(pro?.file_name))
                {
                    extion = pro.file_name.Substring(pro.file_name.LastIndexOf(".") + 1, (pro.file_name.Length - pro.file_name.LastIndexOf(".") - 1));
                }
                dicts.Add(program, extion);
            }

            var result= DNCHttpUtility.DownloadProgramzip(CompanyId, ProjectId, machine.id, dicts);
            return new ObjectResult(result);
        }
        [HttpGet]
        public IActionResult GetContent(int sectionid)
        {
            var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, sectionid);
            var result = DNCHttpUtility.GetProgram(CompanyId, ProjectId, machine.id,"",1);
            return new ObjectResult(result);
        }

        /// <summary>
        /// 获取程序删除页面数据列表
        /// </summary>
        /// <param name="sectionid"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetPgDeletelists(int sectionid, int page = 1, int pagesize = 10)
        {
            var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, sectionid);

            var para = new List<KeyValuePair<string, string>>
            {
                new KeyValuePair<string, string>("machineName", machine.id.ToString())
            };
            var pros = DNCHttpUtility.GetProgramList(CompanyId, ProjectId, para);

            var programs = _sigerProjectDncProgramRepository.GetCheckProgramDeleteList(pros, machine.id);
            var jobPrograms = _dncJobProgramRepository.GetList(q => q.machine_name == machine.id.ToString() && q.projectid == ProjectId).ToList();
            var updatedPrograms = GetUpdatedPrograms(jobPrograms, pros);

            var result = ClcaProgramInfo(machine, pros, programs, updatedPrograms).Skip((page - 1) * pagesize).Take(pagesize);
            return new PagedObjectResult(result, pros.Count, page, pagesize);
        }

        [HttpPost]
        public IActionResult DeleteProgram([FromBody]RequestDownloadProgram req)
        {
            var machine = _sigerProjectDncProgramRepository.GetSectionMachine(ProjectId, req.sectionid);

            var resul = DNCHttpUtility.DeleteProgram(CompanyId, ProjectId, machine.id, req.data);
            return new ObjectResult(resul);
        }
    }
}