using Furion.DependencyInjection;
using Mapster;
using Microsoft.AspNetCore.Hosting;
using MiniExcelLibs;
using Nirvana.Common;
using Nirvana.Common.ApiBase;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YBDevice.Entity;
using YBDevice.NApi.Application.UserInfo;

namespace YBDevice.NApi.Application.DeviceInfo
{
    public class DeviceService : IDeviceService, ITransient
    {
        private readonly ISqlSugarRepository<YB_Device> repository;
        private readonly SqlSugarClient dbClient;
        private readonly IWebHostEnvironment _hostingEnvironment;

        public DeviceService(ISqlSugarRepository<YB_Device> sqlSugarRepository, IWebHostEnvironment hostingEnvironment)
        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _hostingEnvironment = hostingEnvironment;
        }

        /// <summary>
        /// 根据扫码的设备列表导出EXCEL
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<ResultInfo> ExportExcelByScanListAsync(ScanListC2SDto data)
        {
            var list = data.Data.Split(',').ToList();
            string savefolder = _hostingEnvironment.WebRootPath;
            string rootname = $"/files/scan/download";
            string filename = $"{data.Name}_{DateTime.Now.ToString("yyyyMMdd")}.csv";
            string path = Path.Combine(savefolder + "/" + rootname, filename);
            string virtualpath = $"{rootname}/{filename}";
            if (!Directory.Exists(Path.GetDirectoryName(path)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
            }
            else
            {
                //检查文件是否存在
                if (File.Exists(path))
                {
                    return new ResultInfo(ResultState.SUCCESS, "success", virtualpath);
                }
            }
            var savedata = list.Select(x => new { code = x }).ToList();

            var config = new MiniExcelLibs.Csv.CsvConfiguration()
            {
                StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.UTF8)
            };
            await MiniExcel.SaveAsAsync(path, savedata, excelType: ExcelType.CSV, configuration: config);
            return new ResultInfo(ResultState.SUCCESS, "success", virtualpath);
        }

        /// <summary>
        /// 获取设备信息
        /// </summary>
        /// <param name="facecode">设备序列号</param>
        /// <returns></returns>
        public async Task<YB_Device> GetDeviceAsync(string facecode)
        {
            var equ = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.FacCode == facecode);
            //如果设备类型是53或者54,则使用默认设备
            if(equ !=null && (equ.Type == 53 || equ.Type == 54))
            {
                equ = equ.Type == 53? await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Id == 29107): await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Id == 29108);
            }
            return equ;
        }

        /// <summary>
        /// 获取设备信息
        /// </summary>
        /// <param name="ecode">设备机器码</param>
        /// <returns></returns>
        public async Task<YB_Device> GetDeviceByEcodeAsync(string ecode)
        {
            return await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Ecode == ecode);
        }

        /// <summary>
        /// 获取设备
        /// </summary>
        /// <param name="ecode"></param>
        /// <returns></returns>
        public async Task<DeviceAndTypeModel> GetEquAsync(string ecode)
        {
            var data = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Ecode == ecode);
            var types = await dbClient.Queryable<YB_DeviceType>().ToListAsync();
            return new DeviceAndTypeModel
            {
                equ = data,
                types = types
            };
        }

        /// <summary>
        /// 设备列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<YB_Device>> GetListAsync()
        {
            return await dbClient.Queryable<YB_Device>().ToListAsync();
        }

        /// <summary>
        /// 根据设备确定要使用的公众号或者小程序
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<string> GetOfficeByDeviceAsync(YB_Device data)
        {
            var devicetype = await dbClient.Queryable<YB_DeviceType>().FirstAsync(x => x.Code == data.Type);
            if (devicetype.VerType == DeviceVerType.Base)
            {
                return "gh_e2e73d281def"; //每日一称
            }
            return "gh_5efb6d7330a5";
        }

        /// <summary>
        /// 获取设备类型列表
        /// </summary>
        ///<param name="appid">小程序appid</param >
        /// <returns></returns>
        public async Task<ResultInfo> GetTypeListAsync(string appid)
        {
            var newlist = new List<YB_DeviceTypeExt>();
            var AppData = await dbClient.Queryable<YB_DeviceTypeApp>().Where(x => x.Status == StatusType.Enabled && x.AppId == appid).FirstAsync();
            if (AppData != null)
            {
                var ids = AppData.DevType.Split(",").ToList();
                var types = await dbClient.Queryable<YB_DeviceType>().ToListAsync();
                // var InIds = new List<string>();
                types.ForEach(x =>
                {
                    //List<string> newids = x.Content.Split(",").ToList();
                    //bool IsExist = false;
                    //for (var i = 0; i < InIds.Count; i++)
                    //{
                    //    if (newids.Contains(InIds[i]))
                    //    {
                    //        IsExist = true;
                    //        break;
                    //    }
                    //}
                    if (ids.Contains($"{x.Code}")
                    // && !IsExist
                    )
                    {
                        newlist.Add(new YB_DeviceTypeExt
                        {
                            Name = x.ExtName,
                            HeadImg = x.HeadImg,
                            Id = x.Code == 911 ? 11 : x.Code
                        });
                        // InIds.Add($"{x.Code}");
                    }
                });
            }
            var returnlist = newlist.Adapt<List<UserDevTypeS2CDto>>();
            return new ResultInfo(ResultState.SUCCESS, "success", returnlist);
        }

        /// <summary>
        /// 设备注册
        /// </summary>
        /// <param name="yB_Device">设备资料</param>
        /// <returns></returns>
        public async Task<ResultInfo> RegAsync(YB_Device yB_Device)
        {
            yB_Device.Ecode = yB_Device.Ecode.ToStr();
            yB_Device.FacCode = yB_Device.FacCode.ToStr();
            if (await dbClient.Queryable<YB_Device>().AnyAsync(x => x.Ecode == yB_Device.Ecode))
            {
                return new ResultInfo(ResultState.FAIL, "此机器码已存在");
            }
            if (await dbClient.Queryable<YB_Device>().AnyAsync(x => x.FacCode == yB_Device.FacCode))
            {
                return new ResultInfo(ResultState.FAIL, "此序列号已存在");
            }
            //注册设备
            yB_Device.Name = yB_Device.FacCode;
            yB_Device.BusinessId = 0;
            yB_Device.Status = DeviceStatus.UnActive;
            yB_Device.Remark = string.Empty;
            yB_Device.CreateTime = DateTime.Now;
            await dbClient.Insertable(yB_Device).ExecuteCommandAsync();
            return new ResultInfo(ResultState.SUCCESS, "注册成功");
        }

        /// <summary>
        /// YB_Result迁移到YB_nResult
        /// </summary>
        public void Result2NewResult()
        {
            //获取所有的YB_ResultExt,YB_Measure,YB_BodyMeasure

            //var starttime = DateTime.Parse("2021-09-06 07:37:01");
            //var list = dbClient.Queryable<YB_ResultExt, YB_Measure, YB_BodyMeasure>((r, m, s) => new JoinQueryInfos(
            //          JoinType.Left, r.ResultId == m.ResultId,
            //          JoinType.Left, m.ResultId == s.ResultId
            //      ))
            //    .Where((r, m, s) => r.CreateTime > starttime)
            //    .Select((r, m,s) => new ttt
            //    {
            //        Id=r.Id,
            //        ResultId = r.ResultId,
            //        sfr = m.sfr,
            //        Sex=m.Sex,
            //        SfrVal=s.SfrVal,
            //        SkeletalMuscle=s.SkeletalMuscle,
            //        SourceType=r.SourceType,
            //        TakeStatus=1,
            //        Age=m.Age,
            //        bmi=m.bmi,
            //        cmi=m.cmi,
            //        body=m.body,
            //        bodyage=m.bodyage,
            //        BodyFat=s.BodyFat,
            //        BodyFatVal=s.BodyFatVal,
            //        BodyMuscle=s.BodyMuscle,
            //        BodyMuscleVal=s.BodyMuscleVal,
            //        bone=m.bone,
            //        BusinessId=r.BusinessId,
            //        createtime=r.CreateTime,
            //        CreateTime=r.CreateTime,
            //        Ecode=r.Ecode,
            //        EquId=r.EquId,
            //        FacEcode=r.FacEcode,
            //        FamilyId=m.FamilyId,
            //        FansId=r.FansId,
            //        fatlevel=m.fatlevel,
            //        fat_r=m.fat_r,
            //        fat_w=m.fat_w,
            //        Height=m.Height,
            //        IdealWeight=s.IdealWeight,
            //        Imp=r.Imp,
            //        kcal=m.kcal,
            //        lbm=m.lbm,
            //        LeftFootFat=s.LeftFootFat,
            //        LeftFootFatVal=s.LeftFootFatVal,
            //        LeftFootMuscle=s.LeftFootMuscle,
            //        LeftFootMuscleVal=s.LeftFootMuscleVal,
            //        LeftHandFat=s.LeftHandFat,
            //        LeftHandFatVal=s.LeftHandFatVal,
            //        LeftHandMuscle=s.LeftHandMuscle,
            //        LeftHandMuscleVal=s.LeftHandMuscleVal,
            //        LevelJson=s.LevelJson,
            //        Month=m.Month,
            //        muscle=m.muscle,
            //        muscleval=m.muscleval,
            //        OrderId=r.OrderId,
            //        protein=m.protein,
            //        proteinval=m.proteinval,
            //        PublicId=r.PublicId,
            //        RightFootFat=s.RightFootFat,
            //        RightFootFatVal=s.RightFootFatVal,
            //        RightFootMuscle=s.RightFootMuscle,
            //        RightFootMuscleVal=s.RightFootMuscleVal,
            //        RightHandFat=s.RightHandFat,
            //        RightHandFatVal=s.RightHandFatVal,
            //        RightHandMuscle=s.RightHandMuscle,
            //        RightHandMuscleVal=s.RightHandMuscleVal,
            //        UserId=r.UserId,
            //        visceral= m.visceral,
            //        water = m.water,
            //        Weight = m.Weight
            //    })
            //    .ToList();
            //List<YB_nResult> rlist = new List<YB_nResult>();
            //List<YB_nMeasureResult> mlist = new List<YB_nMeasureResult>();
            //List<YB_nUserResult> ulist = new List<YB_nUserResult>();
            //List<YB_nResultAdd> alist = new List<YB_nResultAdd>();
            //list.ForEach(x => {
            //    //添加yb_nresult
            //    var equ = dbClient.Queryable<YB_Device>().First(e => e.Id == x.EquId);
            //    var ybresult = new YB_nResult
            //    {
            //        Id = IDGen.NextID(),
            //        SourceType = x.SourceType,
            //        BusinessId = x.BusinessId,
            //        CreateTime = x.CreateTime,
            //        DevType = equ !=null?equ.Type:1,
            //        EquId = x.EquId,
            //        Height = x.Height,
            //        Imp = x.Imp,
            //        LeftArmImp = 0,
            //        LeftLegImp =0,
            //        RightArmImp = 0,
            //        RightLegImp =0,
            //        Weight = x.Weight
            //    };
            //    rlist.Add(ybresult);
            //    //添加yb_nmeasureresult
            //    var measureresult = new YB_nMeasureResult {
            //        Id = ybresult.Id,
            //        DevType = ybresult.DevType,
            //        sfr = x.sfr,
            //        Sex = x.Sex,
            //        SfrVal =x.SfrVal,
            //        SkeletalMuscle = x.SkeletalMuscle,
            //        Age = x.Age,
            //        bmi = x.bmi,
            //        body = x.body.ToStr(),
            //        bodyage = x.bodyage,
            //        BodyFat = x.BodyFat,
            //        BodyFatVal = x.BodyFatVal,
            //        BodyMuscle =x.BodyMuscle,
            //        BodyMuscleVal =x.BodyMuscleVal,
            //        bone = x.bone,
            //        cmi = x.cmi,
            //        createtime = x.createtime,
            //        fatlevel = x.fatlevel.ToStr(),
            //        fat_r = x.fat_r,
            //        fat_w = x.fat_w,
            //        Height = x.Height,
            //        IdealWeight = x.IdealWeight,
            //        kcal = x.kcal,
            //        lbm = x.lbm,
            //        LeftFootFat =x.LeftFootFat,
            //        LeftFootFatVal = x.LeftFootFatVal,
            //        LeftFootMuscle = x.LeftFootMuscle,
            //        LeftFootMuscleVal =x.LeftFootMuscleVal,
            //        LeftHandFat =x.LeftHandFat,
            //        LeftHandFatVal =x.LeftHandFatVal,
            //        LeftHandMuscle = x.LeftHandMuscle,
            //        LeftHandMuscleVal = x.LeftHandMuscleVal,
            //        Month = x.Month,
            //        muscle = x.muscle,
            //        muscleval = x.muscleval,
            //        protein = x.protein,
            //        proteinval = x.proteinval,
            //        RightFootFat = x.RightFootFat,
            //        RightFootFatVal = x.RightFootFatVal,
            //        RightFootMuscle = x.RightFootMuscle,
            //        RightFootMuscleVal = x.RightFootMuscleVal,
            //        RightHandFat = x.RightHandFat,
            //        RightHandFatVal = x.RightHandFatVal,
            //        RightHandMuscle = x.RightHandMuscle,
            //        RightHandMuscleVal = x.RightHandMuscleVal,
            //        visceral = x.visceral,
            //        water = x.water,
            //        Weight = x.Weight
            //    };
            //    mlist.Add(measureresult);
            //    //添加yb_nuserreasult
            //    var userresult = new YB_nUserResult {
            //        CreateTime = x.CreateTime,
            //        DevType = ybresult.DevType,
            //        FamilyId = x.FamilyId,
            //        FansId = !string.IsNullOrEmpty(x.FansId)?Guid.Parse(x.FansId):null,
            //        Id = ybresult.Id,
            //        UserId = x.UserId
            //    };
            //    ulist.Add(userresult);
            //});
            //if (rlist.Count > 0)
            //{
            //    dbClient.Insertable(rlist).ExecuteCommand();
            //}
            //if (mlist.Count > 0)
            //{
            //    dbClient.Insertable(mlist).ExecuteCommand();
            //}
            //if (ulist.Count > 0)
            //{
            //    dbClient.Insertable(ulist).ExecuteCommand();
            //}
        }

        //public class ttt:YB_Measure
        //{
        //    /// <summary>
        //    /// 躯干肌肉率
        //    /// </summary>
        //    public System.Decimal BodyMuscle { get; set; }

        // ///
        // <summary>
        // /// 左脚肌肉率 ///
        // </summary>
        // public System.Decimal LeftFootMuscle { get; set; }

        // ///
        // <summary>
        // /// 右脚肌肉率 ///
        // </summary>
        // public System.Decimal RightFootMuscle { get; set; }

        // ///
        // <summary>
        // /// 左手肌肉率 ///
        // </summary>
        // public System.Decimal LeftHandMuscle { get; set; }

        // ///
        // <summary>
        // /// 右手肌肉率 ///
        // </summary>
        // public System.Decimal RightHandMuscle { get; set; }

        // ///
        // <summary>
        // /// 躯干脂肪率 ///
        // </summary>
        // public System.Decimal BodyFat { get; set; }

        // ///
        // <summary>
        // /// 左脚脂肪率 ///
        // </summary>
        // public System.Decimal LeftFootFat { get; set; }

        // ///
        // <summary>
        // /// 右脚脂肪率 ///
        // </summary>
        // public System.Decimal RightFootFat { get; set; }

        // ///
        // <summary>
        // /// 左手脂肪率 ///
        // </summary>
        // public System.Decimal LeftHandFat { get; set; }

        // ///
        // <summary>
        // /// 右手脂肪率 ///
        // </summary>
        // public System.Decimal RightHandFat { get; set; }

        // ///
        // <summary>
        // /// 躯干肌肉量 ///
        // </summary>
        // public System.Decimal BodyMuscleVal { get; set; }

        // ///
        // <summary>
        // /// 左脚肌肉量 ///
        // </summary>
        // public System.Decimal LeftFootMuscleVal { get; set; }

        // ///
        // <summary>
        // /// 右脚肌肉量 ///
        // </summary>
        // public System.Decimal RightFootMuscleVal { get; set; }

        // ///
        // <summary>
        // /// 左手肌肉量 ///
        // </summary>
        // public System.Decimal LeftHandMuscleVal { get; set; }

        // ///
        // <summary>
        // /// 右手肌肉量 ///
        // </summary>
        // public System.Decimal RightHandMuscleVal { get; set; }

        // ///
        // <summary>
        // /// 躯干脂肪量 ///
        // </summary>
        // public System.Decimal BodyFatVal { get; set; }

        // ///
        // <summary>
        // /// 左脚脂肪量 ///
        // </summary>
        // public System.Decimal LeftFootFatVal { get; set; }

        // ///
        // <summary>
        // /// 右脚脂肪量 ///
        // </summary>
        // public System.Decimal RightFootFatVal { get; set; }

        // ///
        // <summary>
        // /// 左手脂肪量 ///
        // </summary>
        // public System.Decimal LeftHandFatVal { get; set; }

        // ///
        // <summary>
        // /// 右手脂肪量 ///
        // </summary>
        // public System.Decimal RightHandFatVal { get; set; }

        // ///
        // <summary>
        // /// 皮下脂肪量,kg ///
        // </summary>
        // public System.Decimal SfrVal { get; set; }

        // ///
        // <summary>
        // /// 理想体重 ///
        // </summary>
        // public System.Decimal IdealWeight { get; set; }

        // ///
        // <summary>
        // /// 骨骼肌量,kg ///
        // </summary>
        // public System.Decimal SkeletalMuscle { get; set; }

        // ///
        // <summary>
        // /// 等级标准 ///
        // </summary>
        // public System.String LevelJson { get; set; } ///
        // <summary>
        // /// 阻抗值 ///
        // </summary>
        // public System.Decimal Imp { get; set; }

        // ///
        // <summary>
        // /// 设备ID ///
        // </summary>
        // public System.Int32 EquId { get; set; }

        // ///
        // <summary>
        // /// 设备机器码 ///
        // </summary>
        // public System.String Ecode { get; set; }

        // ///
        // <summary>
        // /// 设备序列号 ///
        // </summary>
        // public System.String FacEcode { get; set; }

        // ///
        // <summary>
        // /// 来源,1-蓝牙传输,2-手动记录,3-扫码记录 ///
        // </summary>
        // public System.Int32 SourceType { get; set; }

        // ///
        // <summary>
        // /// 使用的订单ID ///
        // </summary>
        // public System.Guid OrderId { get; set; }

        // ///
        // <summary>
        // /// 所属的公众号/小程序 ///
        // </summary>
        // public System.String PublicId { get; set; }

        // ///
        // <summary>
        // /// 扫码时使用的用户唯一标识 ///
        // </summary>
        // public System.String FansId { get; set; }

        // ///
        // <summary>
        // /// 用户ID ///
        // </summary>
        // public System.Int32 UserId { get; set; }

        // ///
        // <summary>
        // /// 客户ID ///
        // </summary>
        // public System.Int32 BusinessId { get; set; }

        //    /// <summary>
        //    /// 创建时间
        //    /// </summary>
        //    public System.DateTime CreateTime { get; set; }
        //}
    }
}