using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using APT.BaseData.Domain.ApiModel.OP;
using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Entities.OP;
using APT.BaseData.Domain.Enums.PF;
using APT.CMS.Domain.ApiModel;
using APT.CMS.Domain.Entities.CP;
using APT.Infrastructure.Api;
using APT.Infrastructure.Api.Redis;
using APT.Infrastructure.Core;
using APT.Utility;
using Microsoft.AspNetCore.Mvc;
using APT.BaseData.Domain.ApiModel.Platform;

namespace APT.OP.WebApi.Controllers.Api
{
    [Route("api/OP/OPFileFirmware")]
    public class FileFirmwareController : APTApiController<T_OP_FILE_FIRMWARE>
    {
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("UploadFile")]
        public JsonActionResult<OPFileReulst> UploadFile()
        {
            return SafeExecute(() =>
            {
                string result = string.Empty;
                List<T_OP_FILE_FIRMWARE> fileList = new List<T_OP_FILE_FIRMWARE>();

                var httpRequest = HttpContext.Request;
                var strOrgId = httpRequest.Form["OrgId"][0];  // 获取 组织
                var isSaveSelfStr = httpRequest.Form["IsSaveSelf"].Any() ? httpRequest.Form["IsSaveSelf"][0] : "false";  // 是否存储本身
                if (string.IsNullOrEmpty(strOrgId))
                    throw new Exception("组织不允许为空");
                var orgId = new Guid(strOrgId);
                // 获取 组织

                //返回的文件地址
                List<string> filenames = new List<string>();
                var now = DateTime.Now;
                //文件存储路径
                var filePath = string.Format("/{0}/{1}/{2}/", now.ToString("yyyy"), now.ToString("yyyyMM"), now.ToString("yyyyMMdd"));
                var fullFilePath = $"{ ConfigurationManager.AppSettings["Firmware_Local"]}{filePath}";
                var files = httpRequest.Form.Files;

                if (!Directory.Exists(fullFilePath))
                {
                    Directory.CreateDirectory(fullFilePath);
                }
                try
                {
                    foreach (var item in files)
                    {
                        if (item != null)
                        {
                            //文件后缀
                            var fileExtension = Path.GetExtension(item.FileName);
                            var strDateTime = DateTime.Now.ToString("yyMMddhhmmssfff"); //取得时间字符串
                            var strRan = Convert.ToString(new Random().Next(100, 999)); //生成三位随机数
                            var saveName = strDateTime + strRan + fileExtension;

                            //判断文件大小    
                            long length = item.Length;
                            if (length > 1024 * 1024 * 4) //4M
                            {
                                break;
                                //return Error("上传的文件不能大于4M");
                            }

                            //插入图片数据
                            using (FileStream fs = System.IO.File.Create(fullFilePath + saveName))
                            {
                                item.CopyTo(fs);
                                fs.Flush();
                            }
                            filenames.Add(filePath + saveName);
                            T_OP_FILE_FIRMWARE file = new T_OP_FILE_FIRMWARE
                            {
                                ID = Guid.NewGuid(),
                                FIRMWARE_PATH = filePath + saveName,
                                ORG_ID = orgId,
                                FIRMWARE_NAME = item.FileName,
                                FIRMWARE_TYPE = item.ContentType,
                                FIRMWARE_VERSION = strDateTime + strRan
                            };
                            Byte[] fileData = new Byte[item.Length];
                            Stream sr = item.OpenReadStream();//创建数据流对象 
                            sr.Read(fileData, 0, (int)item.Length);
                            file.FIRMWARE_DATA = fileData;
                            fileList.Add(file);
                        }
                    }
                    if (fileList.Count > 0)
                        BantchAddEntity(fileList);

                    return new OPFileReulst() { Result = true, FilePath = filenames };
                }
                catch (Exception ex)
                {
                    //这边增加日志，记录错误的原因
                    //ex.ToString();
                    return new OPFileReulst() { Result = false, ErrorMsg = "文件不存在" };
                }

            });
        }

        /// <summary>
        /// 查询所有租户充电桩
        /// </summary>
        /// <param name="pageFilter"></param>
        /// <returns></returns>
        [HttpPost, Route("OrderPagedAllPile")]
        public PagedActionResult<T_CP_CHARGING_PILE> OrderPagedAllPile([FromBody] KeywordPageFilter pageFilter)
        {
            return SafeGetPagedData<T_CP_CHARGING_PILE>((result) =>
            {
                var tenant = pageFilter.Parameter1;
                var filter = new KeywordPageFilter
                {
                    FilterGroup = pageFilter.FilterGroup
                };

                filter.IgnoreOrgRule = true;
                if (tenant == null)
                {
                    filter.IsMultipleDb = true;
                }
                else
                {
                    filter.IsSpecifyDb = true;
                    filter.SpecifyTenant = tenant;
                }
                var piles = GetOrderPageEntities<T_CP_CHARGING_PILE>(null, filter);
                result.Data = piles.Data;
                result.TotalCount = piles.TotalCount;
            });
        }

        /// <summary>
        /// 固件升级
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("UpdateFirmware")]
        public JsonActionResult<bool> UpdateFirmware([FromBody] KeywordFilter filter)
        {
            return SafeExecute(() =>
            {
                if (filter.Keyword == null)
                    return false;
                var arrIds = filter.Keyword.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(i => new Guid(i));
                filter.IgnoreOrgRule = true;
                filter.Sort = "CREATE_TIME";
                filter.Order = DbOrder.DESC;
                filter.SelectField = new string[]
                {
                    "FIRMWARE_VERSION"
                };
                var firmware = GetEntity<T_OP_FILE_FIRMWARE>(null, filter);
                if (firmware == null)
                    return false;

                var baseFilter = new BaseFilter
                {
                    IgnoreOrgRule = true,
                    IsMultipleDb = true,

                };
                var piles = GetEntities<T_CP_CHARGING_PILE>(x => arrIds.Contains(x.ID), baseFilter);
                piles.Select(x => x.FIRMWARE_VERSION = firmware.FIRMWARE_VERSION);
                var group = piles.GroupBy(x => x.DbConn);
                foreach (var item in group)
                {
                    UpdateEntitiesByConn(item.ToList(), item.Key, "FIRMWARE_VERSION");
                }
                #region 给终端发布指令
                var groupByOrg = piles.GroupBy(x => x.ORG_ID);
                var mqConfs = this.GetEntitiesByRedis<T_PF_MQTT_CONFIG>(null, baseFilter, "", "Nav_MqttConfigTheme");
                foreach (var item in mqConfs)
                {
                    var mqName = item.NAME + "_" + item.ORG_ID;
                    var groupPiles = groupByOrg.FirstOrDefault(x => x.Key == item.ORG_ID);
                    foreach (var pile in groupPiles)
                    {
                        var mqttTheme = new MqttMesage
                        {
                            cmd = PFThemeTypeEnum.P_版本升级.ToString(),
                            firmware_version = firmware.FIRMWARE_VERSION,
                            url = firmware.FIRMWARE_PATH,
                            timestamp = DataHelper.GetTimeSpanFrom1970Ticks(DateTime.Now),
                            terminal_no = pile.CODE,
                            terminal_sn = pile.SEQUENCE,
                        };
                        CsRedisManager.GetClient().LPush(mqName.GetPubRedisKey(), mqttTheme);
                    }
                }
                #endregion
                return true;
            });
        }

    }
}
