using MoYu.RemoteRequest.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SafeCampus.Application.Manager.DeepelephManager;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;

namespace SafeCampus.Application.Services.Business.CameraInfoService;

public class CameraInfoService:DbRepository<CameraInfo>, ICameraInfoService
{
    private readonly IDeepelephManager _deepelephManager;
    private readonly ISimpleCacheService _simpleCacheService;

    public CameraInfoService(IDeepelephManager deepelephManager, ISimpleCacheService simpleCacheService)
    {
        _deepelephManager = deepelephManager;
        _simpleCacheService = simpleCacheService;
    }

    public async Task<bool> DataSync()
    {
        var appSettings = App.GetOptionsMonitor<AppInfoOptions>();
        var list = await Context.Queryable<CameraInfo>().ToListAsync();
        var str = await $"{appSettings.SXAPIURL}/device/console/v1/sensor/page_query/brief"
            .SetBody(new
            {
                token = _deepelephManager.GetToken(),
                tenantCode = appSettings.TenantCode,
                poiId = appSettings.PoiId,
                pageNo = 1,
                pageSize = 1000,
            })
            .SetContentType("application/json")
            .PostAsAsync<string>();
        var model = JsonConvert.DeserializeObject<JObject>(str);
        if (!(bool)model["success"]) throw Oops.Oh(model["message"].ToString());
        if (model["data"] != null)
        {
            foreach (var item in model["data"]["items"])
            {
                var old_model = list.FirstOrDefault(x => x.SensorId == item["sensorId"].ToString());
                if (old_model != null)
                {
                    old_model.DeviceStatus = item["deviceStatus"].ToString() == "online";
                    old_model.DirectUrlIp = item["directUrlIp"].ToString();
                    old_model.FieldId = item["fieldId"].ToString();
                    old_model.FieldName = item["fieldName"].ToString();
                    old_model.LastTime = DateTime.Now;
                    old_model.ResHeight = (int)item["resHeight"];
                    old_model.ResWidth = (int)item["resWidth"];
                    old_model.SensorName = item["sensorName"].ToString();
                    old_model.SnapshotUrl = item["snapshotUrl"].ToString();
                    var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:CameraImg"], old_model.SensorId + ".jpg");
                    var steam = await old_model.SnapshotUrl.GetAsByteArrayAsync();
                    using (MemoryStream ms = new MemoryStream(steam))
                    {
                        using (Bitmap bmp = new Bitmap(ms))
                        {
                            using (Graphics g = Graphics.FromImage(bmp))
                            {
                                
                            }
                            bmp.Save(signImg, ImageFormat.Jpeg);
                        }
                    }
                    old_model.SnapshotUrl = $"/Files/{App.Configuration["AppInfo:CameraImg"]}/{old_model.SensorId}.jpg";
                    await UpdateAsync(old_model);
                }
                else
                {
                    var cameraModel = new CameraInfo
                    {
                        DeviceStatus = item["deviceStatus"].ToString() == "online",
                        DirectUrlIp = item["directUrlIp"].ToString(),
                        FieldId = item["fieldId"].ToString(),
                        FieldName = item["fieldName"].ToString(),
                        LastTime = DateTime.Now,
                        ResHeight = (int)item["resHeight"],
                        ResWidth = (int)item["resWidth"],
                        SensorId = item["sensorId"].ToString(),
                        SensorName = item["sensorName"].ToString(),
                        SnapshotUrl = item["snapshotUrl"].ToString(),

                    };
                    var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:CameraImg"], cameraModel.SensorId + ".jpg");
                    var steam = await cameraModel.SnapshotUrl.GetAsByteArrayAsync();
                    using (MemoryStream ms = new MemoryStream(steam))
                    {
                        using (Bitmap bmp = new Bitmap(ms))
                        {
                            using (Graphics g = Graphics.FromImage(bmp))
                            {

                            }
                            bmp.Save(signImg, ImageFormat.Jpeg);
                        }
                    }
                    cameraModel.SnapshotUrl = $"/Files/{App.Configuration["AppInfo:CameraImg"]}/{cameraModel.SensorId}.jpg";
                    await InsertAsync(cameraModel);
                }
            }
            return true;
        }
        return false;
    }

    public async Task<SqlSugarPagedList<CameraInfoDto>> GetPageList(CameraSearch search)
    {
        var query = Context.Queryable<CameraInfo>()
            .Includes(x=>x.SysUserItem)
            .Includes(x=>x.CameraGroupItem)
            .WhereIF(search.DeviceStatus.HasValue, x => x.DeviceStatus == search.DeviceStatus)
            .WhereIF(!string.IsNullOrEmpty(search.SensorId), x => x.SensorId == search.SensorId)
            .WhereIF(!string.IsNullOrEmpty(search.SensorName), x => x.SensorName == search.SensorName)
            .WhereIF(search.GroupId.HasValue, x => (search.GroupId.Value==-1?x.GroupId==null:x.GroupId==search.GroupId.Value));
        var list = await query.OrderBy(x => x.LastTime)
            .ToPagedListAsyncMapster<CameraInfo, CameraInfoDto>(search.PageNum, search.PageSize);
        return list;
    }

    public async Task<bool> BatchSetGroup(SetGroupInput input)
    {
        if (input.Id==-1)
        {
            var result = await Context.Updateable<CameraInfo>()
                .SetColumns(x => x.GroupId == null)
                .Where(x => input.Ids.Contains(x.Id))
                .ExecuteCommandAsync();
            return result == input.Ids.Count;
        }
        else
        {
            var result = await Context.Updateable<CameraInfo>()
                .SetColumns(x => x.GroupId == input.Id)
                .Where(x => input.Ids.Contains(x.Id))
                .ExecuteCommandAsync();
            return result == input.Ids.Count;
        }
    }

    public async Task<bool> BatchSetPushPersonByGroup(SetPushPersonGroupInput input)
    {
        var result = await Context.Updateable<CameraInfo>()
            .SetColumns(x => x.PushUserId == input.UserId)
            .Where(x =>x.GroupId==input.GroupId)
            .ExecuteCommandAsync();
        return result >0;
    }

    public async Task<bool> BatchSetPushPerson(SetPushPersonInput input)
    {
        var result = await Context.Updateable<CameraInfo>()
            .SetColumns(x => x.PushUserId == input.UserId)
            .Where(x => input.Ids.Contains(x.Id))
            .ExecuteCommandAsync();
        return result == input.Ids.Count;
    }

    public async Task<bool> BatchSetPushPersonByWarn(SetPushPersonWarnInput input)
    {
        var warn = _simpleCacheService.Get<List<WarnGroupInfo>>(SafeCampusConst.WarnGroup);
        var warnGroupInfo = warn.FirstOrDefault(x => x.Code == input.WarnCode);
        if (warnGroupInfo != null)
        {
            var ids = warnGroupInfo.CameraId;
            var result = await Context.Updateable<CameraInfo>()
                .SetColumns(x => x.PushUserId == input.UserId)
                .Where(x => ids.Contains(x.SensorId))
                .ExecuteCommandAsync();
            return result >0;
        }

        throw Oops.Oh("分组不存在");
    }
}