using dodohold.core;
using Dataoke;
using Tea;
using AlibabaCloud.SDK.BssOpenApi20171214.Models;
using AlibabaCloud.SDK.Ecs20140526.Models;
using AlibabaCloud.SDK.Vpc20160428.Models;
using TencentCloud.Dbbrain.V20210527.Models;
using Org.BouncyCastle.Bcpg.OpenPgp;
using TencentCloud.Tke.V20180525.Models;
using static molilian.core.TkPoolCore;
using ZstdSharp.Unsafe;
using System.Collections.Generic;

namespace molilian.core
{

    public partial class AliyunPoolCore
    {

        private static readonly object _lockObj = new();
        private static IEnumerable<AliyunPoolDTO> _cached;

        public static AliyunPoolDTO? GetOne(int id)
        {
            var list = List();
            if (!list.Any()) return null;
            return list.Where(e => e.id == id).FirstOrDefault();
        }

        public static IEnumerable<AliyunPoolDTO> List(bool force = false)
        {

            if (!force && _cached != null) return _cached;

            string cache_key = $"cache:aliyun_pool";
            var list = RedisHelper.Get<IEnumerable<AliyunPoolDTO>>(cache_key);
            if (force || list == null)
            {
                lock (_lockObj)
                {
                    list = new DBContext.Table("aliyun_pool")
                        .Where("status=@status", new { status = 1 })
                        .Select<AliyunPoolDTO>();

                    list = new DBContext.Table("aliyun_pool")
                        .Where("status=@status", new { status = 1 })
                        .Select<AliyunPoolDTO>();
                    if (list == null) return default;
                    RedisHelper.Set(cache_key, list, 30 * 86400);
                }
            }
            _cached = list;
            return list;
        }
        public static void Refresh()
        {
            _ = List(true);
        }
        public static void UpdateDrawBalance(string name, decimal amout)
        {
            new DBContext.Table("aliyun_pool")
                .Add("balance", amout)
                .Add("last_time", DateTime.Now)
                .Where("name=@name", new { name })
                .Update();
            _ = List(true);
        }


        public void GetBlances()
        {
            var list = new DBContext.Table("aliyun_pool").Where(string.Empty, new { }).Select<AliyunPoolDTO>();
            foreach (var item in list)
            {
                if (string.IsNullOrEmpty(item.accessKeyId)) continue;

                decimal amout = 0;
                try
                {
                    AliyunCore core = new AliyunCore(item);
                    var response = core.QueryAccountBalance();
                    var balance = response.Body.Data.AvailableAmount;
                    if (decimal.TryParse(balance, out amout))
                    {
                        UpdateDrawBalance(item.name, amout);
                        if (item.balance != amout && amout <= item.balance_alert_threshold)
                        {
                            string message = $"【{item.company}】阿里云当前余额：{amout} 元";
                            _ = NotifyCore.QYWeixinPushNotifyAsync("余额预警", message);
                            NotifyCore.Notify(new NifyMessage
                            {
                                message = message,
                                priority = NifyMessagePriority.high,
                                tags = ["red_circle"]
                            });
                        }
                    }
                }
                catch (Exception ex)
                {
                    new LoggerLibrary("aliyun", "balance_error")
                    .Info($"Account:{item.id}\tbalance:{amout}")
                    .Info(ex.Message, ex.StackTrace)
                    .SaveAsync();
                }
            }
        }



        public static List<AliyunEcsDTO> EcsList(AliyunPoolDTO item)
        {
            List<AliyunEcsDTO> result = [];
            decimal amout = 0;
            try
            {
                AliyunCore core = new AliyunCore(item);
                var regions = item.regions.Split(',');
                foreach (var region in regions)
                {
                    var instances = core.GetInstances(region);
                    foreach (var instance in instances.Instance)
                    {
                        var data = new AliyunEcsDTO();

                        data.cpu = (int)instance.Cpu;
                        data.instance_id = instance.InstanceId;
                        data.instance_name = instance.InstanceName;
                        data.host_name = instance.HostName;

                        if (DateTime.TryParse(instance.ExpiredTime, out DateTime expired_time))
                        {
                            data.expired_time = expired_time;
                        }
                        if (DateTime.TryParse(instance.CreationTime, out DateTime creation_time))
                        {
                            data.creation_time = creation_time;
                        }
                        data.memory = (int)instance.Memory / 1024;
                        data.region_id = instance.RegionId;
                        data.instance_type = instance.InstanceType;

                        var networks = core.DescribeNetworkInterfaces(data.region_id, data.instance_id);

                        data.AddressIps = new List<AddressIpDTO>();
                        foreach (var networkInterface in networks)
                        {
                            //找出网卡信息
                            string networkInterfaceId = networkInterface.NetworkInterfaceId;
                            var privateIps = networkInterface?.PrivateIpSets;
                            foreach (var taraget in privateIps.PrivateIpSet)
                            {
                                string privateIp = taraget.PrivateIpAddress;
                                //找到当前公网IP
                                string currentPublicIp = taraget?.AssociatedPublicIp?.PublicIpAddress;
                                if (string.IsNullOrEmpty(currentPublicIp))
                                {
                                    var currentEips = core.DescribeEipsAddresse(region, string.Empty);
                                    var currentEip = currentEips?.Where(e => privateIp.Equals(e.PrivateIpAddress))?.FirstOrDefault();
                                    currentPublicIp = currentEip?.IpAddress;

                                    if (string.IsNullOrEmpty(currentPublicIp))
                                    {
                                        var emptyPrivateEips = currentEips?.Where(e => string.IsNullOrEmpty(e.PrivateIpAddress));
                                        foreach (var emptyEip in emptyPrivateEips)
                                        {
                                            var body = core.DescribeNetworkInterfaceAttribute(region, emptyEip.InstanceId);
                                            if (body != null)
                                            {
                                                if (body.PrivateIpAddress == privateIp)
                                                {
                                                    currentPublicIp = emptyEip?.IpAddress;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                                data.AddressIps.Add(new AddressIpDTO
                                {
                                    networkInterfaceId = networkInterfaceId,
                                    privateIp = privateIp,
                                    publicIp = currentPublicIp,
                                });
                            }
                        }
                        result.Add(data);
                    }

                }

            }
            catch (Exception ex)
            {
                new LoggerLibrary("aliyun", "balance_error")
                .Info($"Account:{item.id}\tbalance:{amout}")
                .Info(ex.Message, ex.StackTrace)
                .SaveAsync();
            }
            return result;
        }

        public static List<AliyunEcsDTO> EcsList()
        {
            List<AliyunEcsDTO> result = new List<AliyunEcsDTO>();
            var list = new DBContext.Table("aliyun_pool").Where(string.Empty, new { }).Select<AliyunPoolDTO>();
            foreach (var item in list)
            {
                if (string.IsNullOrEmpty(item.accessKeyId)) continue;

                decimal amout = 0;
                try
                {
                    AliyunCore core = new AliyunCore(item);
                    var regions = item.regions.Split(',');
                    foreach (var region in regions)
                    {
                        var instances = core.GetInstances(region);
                        foreach (var instance in instances.Instance)
                        {
                            var data = new AliyunEcsDTO();

                            data.cpu = (int)instance.Cpu;
                            data.instance_id = instance.InstanceId;
                            data.instance_name = instance.InstanceName;
                            data.host_name = instance.HostName;

                            if (DateTime.TryParse(instance.ExpiredTime, out DateTime expired_time))
                            {
                                data.expired_time = expired_time;
                            }
                            if (DateTime.TryParse(instance.CreationTime, out DateTime creation_time))
                            {
                                data.creation_time = creation_time;
                            }
                            data.memory = (int)instance.Memory / 1024;
                            data.region_id = instance.RegionId;
                            data.instance_type = instance.InstanceType;

                            var networks = core.DescribeNetworkInterfaces(data.region_id, data.instance_id);

                            data.AddressIps = new List<AddressIpDTO>();
                            foreach (var networkInterface in networks)
                            {
                                //找出网卡信息
                                string networkInterfaceId = networkInterface.NetworkInterfaceId;
                                var privateIps = networkInterface?.PrivateIpSets;
                                foreach (var taraget in privateIps.PrivateIpSet)
                                {
                                    //找到当前公网IP
                                    string currentPublicIp = taraget?.AssociatedPublicIp?.PublicIpAddress;

                                    data.AddressIps.Add(new AddressIpDTO
                                    {
                                        networkInterfaceId = networkInterfaceId,
                                        privateIp = taraget.PrivateIpAddress,
                                        publicIp = currentPublicIp,
                                    });
                                }
                            }
                            result.Add(data);
                        }

                    }

                }
                catch (Exception ex)
                {
                    new LoggerLibrary("aliyun", "balance_error")
                    .Info($"Account:{item.id}\tbalance:{amout}")
                    .Info(ex.Message, ex.StackTrace)
                    .SaveAsync();
                }
            }
            return result;
        }

    }


}

