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 AlibabaCloud.SDK.Ecs20140526.Models.DescribeInstancesResponseBody;
using static AlibabaCloud.SDK.Ecs20140526.Models.DescribeNetworkInterfacesResponseBody;
using static AlibabaCloud.SDK.Vpc20160428.Models.DescribeEipAddressesResponseBody.DescribeEipAddressesResponseBodyEipAddresses;
using AlibabaCloud.SDK.ImageSearch20210501.Models;
using static AlibabaCloud.SDK.Ecs20140526.Models.DescribeNetworkInterfacesResponseBody.DescribeNetworkInterfacesResponseBodyNetworkInterfaceSets;
using TencentCloud.Cam.V20190116.Models;
using static AlibabaCloud.SDK.Vpc20160428.Models.DescribeNetworkAclAttributesResponseBody;
using static AlibabaCloud.SDK.Ecs20140526.Models.DescribeNetworkInterfaceAttributeResponseBody;

namespace molilian.core
{

    public partial class AliyunCore
    {
        private AliyunPlus plus;
        public AliyunPoolDTO _account;

        public AliyunCore(int id)
        {
            _account = new DBContext.Table("aliyun_pool").Get<AliyunPoolDTO>(id);
            if (_account == null) throw new Exception("无效账号");
            plus = new AliyunPlus(_account.accessKeyId, _account.accessKeySecret);
        }
        public AliyunCore(AliyunPoolDTO item)
        {
            _account = item;
            plus = new AliyunPlus(_account.accessKeyId, _account.accessKeySecret);
        }


        public AliyunCore(string accessKeyId, string accessKeySecret)
        {
            plus = new AliyunPlus(accessKeyId, accessKeySecret);
        }

        public async Task<SearchByPicResponse> SearchByPicAsync(string base64String, string pid)
        {
            return await plus.SearchByPicAsync(base64String, pid);
        }

        public async Task<PromotionQueryDTO> picSimilaritemAsync(string pic, string pid, PromotionQueryDTO result, bool useCouponLinkFirst = true)
        {
            var response = await plus.SearchByPicAsync(pic, pid);
            if (response == null)
            {
                result.message = "调用失败";
                result.reason = "内部错误";
                return result;
            }

            result.success = (bool)response.Body.Success;
            if (!result.success)
            {
                result.message = "调用失败";
                result.reason = $"{response.Body.Code}:{response.Body.Message}";
                return result;
            }


            List<PromotionQueryItemDTO> arr = [];
            foreach (var e in response.Body.Data.Auctions)
            {
                var item = e.Result;

                PromotionQueryItemDTO newItem = new()
                {
                    itemId = item.ItemId,
                    h5_url = useCouponLinkFirst && !string.IsNullOrEmpty(item.CouponShareUrl) ? item.CouponShareUrl : item.Url,
                    deeplink_url = useCouponLinkFirst && !string.IsNullOrEmpty(item.DeeplinkCouponShareUrl) ? item.DeeplinkCouponShareUrl : item.DeeplinkUrl,
                    userType = $"{item.UserType}",
                    shopTitle = item.ShopTitle,
                    itemName = item.Title,
                    pic = item.PicUrl,
                    price = item.ReservePrice,
                    zkFinalPrice = item.ZkFinalPrice,
                    promotionPrice = item.PriceAfterCoupon,
                    couponAmount = $"{item.CouponAmount}",
                    couponEffectiveStartTime = item.CouponStartTime,
                    couponEffectiveEndTime = item.CouponEndTime,
                    sellCountStr = $"{item.Volume}",
                    provcity = item.Provcity,
                    exposeTracks = $"https://api.molilian.com/tracks/track?track_id=7&unique_id={item.ItemId}",
                    clickTracks = $"https://api.molilian.com/tracks/track?track_id=8&unique_id={item.ItemId}"
                };

                if (newItem.h5_url.StartsWith("//")) newItem.h5_url = "https:" + newItem.h5_url;
                if (newItem.pic.StartsWith("//")) newItem.pic = "https:" + newItem.pic;
                arr.Add(newItem);
            }

            result.message = "OK";
            result.reason = string.Empty;
            result.PromotionImg = arr;
            return result;
        }

        public async Task<PromotionQueryDTO> itemSimilaritemAsync(string itemids, string pid, PromotionQueryDTO result)
        {
            var response = await plus.GetProductInfoByIds(itemids, pid);
            if (response == null)
            {
                result.message = "调用失败";
                result.reason = "内部错误";
                return result;
            }

            result.success = (bool)response.Body.Success;
            if (!result.success)
            {
                result.message = "调用失败";
                result.reason = $"{response.Body.Code}:{response.Body.Message}";
                return result;
            }


            List<PromotionQueryItemDTO> arr = [];
            foreach (var e in response.Body.Data.Auctions)
            {
                var item = e.Result;

                PromotionQueryItemDTO newItem = new()
                {
                    itemId = item.ItemId,
                    h5_url = string.IsNullOrEmpty(item.CouponShareUrl) ? item.Url : item.CouponShareUrl,
                    deeplink_url = string.IsNullOrEmpty(item.DeeplinkCouponShareUrl) ? item.DeeplinkUrl : item.DeeplinkCouponShareUrl,
                    userType = $"{item.UserType}",
                    shopTitle = item.ShopTitle,
                    itemName = item.Title,
                    pic = item.PicUrl,
                    price = item.ReservePrice,
                    zkFinalPrice = item.ZkFinalPrice,
                    promotionPrice = item.PriceAfterCoupon,
                    couponAmount = $"{item.CouponAmount}",
                    couponEffectiveStartTime = item.CouponStartTime,
                    couponEffectiveEndTime = item.CouponEndTime,
                    sellCountStr = $"{item.Volume}",
                    provcity = item.Provcity,
                    exposeTracks = $"https://api.molilian.com/tracks/track?track_id=7&unique_id={item.ItemId}",
                    clickTracks = $"https://api.molilian.com/tracks/track?track_id=8&unique_id={item.ItemId}"
                };

                if (newItem.h5_url.StartsWith("//")) newItem.h5_url = "https:" + newItem.h5_url;
                if (newItem.pic.StartsWith("//")) newItem.pic = "https:" + newItem.pic;
                arr.Add(newItem);
            }

            result.message = "OK";
            result.reason = string.Empty;
            result.PromotionImg = arr;
            return result;
        }



        public QueryAccountBalanceResponse QueryAccountBalance()
        {
            return plus.QueryAccountBalance();
        }

        /// <summary>
        /// 获取这个地区下的所有ecs
        /// </summary>
        /// <param name="region"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public DescribeInstancesResponseBodyInstances GetInstances(string region)
        {
            try
            {
                //查询实例信息
                var response = plus.DescribeInstances(region);
                var Instances = response.Body.Instances;
                return Instances;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        public DescribeNetworkInterfacesResponseBodyNetworkInterfaceSets GetNetworkInterfaces(string region)
        {
            try
            {
                //查询实例信息
                var response = plus.DescribeNetworkInterfaces(region);
                var networkInterfaces = response.Body.NetworkInterfaceSets;
                return networkInterfaces;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        //public bool xxx(string region, string instanceId, string privateIp)
        //{
        //    try
        //    {
        //        //查询实例信息
        //        var instance = plus.DescribeInstanceAttribute(region, instanceId);
        //        var vswitchId = instance.Body.VpcAttributes.VSwitchId;
        //        var securityGroupId = instance.Body.SecurityGroupIds.SecurityGroupId;

        //        plus.DescribeNetworkInterfaces(region, instanceId)
        //        //释放弹性网卡
        //        ReleaseEipAddress("cn-beijing", allocationId);
        //        //申请并绑定公网IP
        //        EcsAssociateEipAddress(region, networkInterfaceId, privateIpAddress);
        //        return true;
        //    }
        //    catch (Exception ex)
        //    {
        //        throw new Exception(ex.Message);
        //    }
        //}



        public async Task<(bool, string, string)> ChangePublicIpAsync(string privateIp)
        {
            LoggerLibrary log = new LoggerLibrary("ChangePublicIp");
            log.Info($"=====更改公网IP：{privateIp}=====");
            try
            {
                var regions = _account.regions?.Split(',');
                foreach (var s in regions)
                {
                    var region = s.Trim();
                    if (string.IsNullOrEmpty(region)) continue;

                    //获取这个地区下的所有网卡
                    var list = GetNetworkInterfaces(region);
                    if (list == null) continue;

                    foreach (var networkInterface in list.NetworkInterfaceSet)
                    {
                        //找出网卡信息
                        string networkInterfaceId = networkInterface.NetworkInterfaceId;
                        var privateIps = networkInterface?.PrivateIpSets;

                        var taraget = privateIps?.PrivateIpSet.Where(e => e.PrivateIpAddress.Equals(privateIp)).FirstOrDefault();
                        if (taraget == null) continue;


                        //找到当前公网IP
                        string currentPublicIp = taraget?.AssociatedPublicIp?.PublicIpAddress;
                        DescribeEipAddressesResponseBodyEipAddressesEipAddress currentEip;
                        if (string.IsNullOrEmpty(currentPublicIp))
                        {
                            await Task.Delay(500);
                            var currentEips = DescribeEipsAddresse(region, string.Empty);
                            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)
                                {
                                    await Task.Delay(500);
                                    var body = DescribeNetworkInterfaceAttribute(region, emptyEip.InstanceId);
                                    if (body != null)
                                    {
                                        if (body.PrivateIpAddress == privateIp)
                                        {
                                            currentEip = emptyEip;
                                            currentPublicIp = emptyEip?.IpAddress;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            await Task.Delay(500);
                            currentEip = DescribeEipAddresse(region, currentPublicIp) ?? throw new Exception("没有找到 EIP");
                        }
                        log.Info($"找到当前公网IP：{currentPublicIp}");
                        if (currentEip == null) throw new Exception("没有找到 EIP");

                        //第1步、获取当前的公网EIP
                        var currentAllocationId = currentEip.AllocationId;
                        log.Info($"获取当前的公网EIP:{currentAllocationId}");

                        //第2步、申请新的公网ip
                        await Task.Delay(500);
                        var eip = plus.AllocateEipAddress(region);
                        var allocationId = eip.Body.AllocationId;
                        string eipAddress = eip.Body.EipAddress;

                        if (string.IsNullOrEmpty(eipAddress))
                        {
                            log.Info("申请新的公网ip 可能出现异常", eip.Convert2Json());
                        }
                        else
                        {
                            log.Info($"申请新的公网ip:{eipAddress}");
                        }


                        //第3步、解绑当前的公网ip
                        await Task.Delay(500);
                        plus.UnassociateEipAddress(region, currentAllocationId);

                        log.Info("解绑当前的公网ip");

                        //第4步、检查公网ip是否成功解绑
                        string unPublicIpAddress = currentPublicIp;

                        log.Info("检查公网ip是否成功解绑");

                        while (!string.IsNullOrEmpty(unPublicIpAddress))
                        {
                            await Task.Delay(500);
                            var networkInterfaceState = plus.DescribeNetworkInterfaceAttribute(region, networkInterfaceId);
                            var currentPrivateIpSet = networkInterfaceState?.Body?.PrivateIpSets?.PrivateIpSet;

                            var currentPrivateIpAddress = currentPrivateIpSet.Where(e => e.PrivateIpAddress.Equals(privateIp)).FirstOrDefault();
                            unPublicIpAddress = currentPrivateIpAddress?.AssociatedPublicIp?.PublicIpAddress;

                            log.Info($"{unPublicIpAddress} 还没解绑");

                            if (string.IsNullOrEmpty(unPublicIpAddress)) break;
                            await Task.Delay(500);
                        }
                        log.Info("公网ip成功解绑");


                        await Task.Delay(1500);
                        //第5步、绑定新的公网ip
                        var AssociateEipAddress =
                            plus.AssociateEipAddress(region, allocationId, networkInterfaceId, EIPInstanceType.NetworkInterface, privateIp);

                        log.Info($"绑定新的公网ip", AssociateEipAddress.Convert2Json());
                        await Task.Delay(500);
                        //第5步、释放当前的公网IP
                        plus.ReleaseEipAddress(region, currentAllocationId);
                        log.Info($"释放当前的公网IP");
                        return (true, currentPublicIp, eipAddress);
                    }
                }
                throw new Exception("没有符合的数据");

            }
            catch (Exception ex)
            {
                log.Info($"发生异常：{ex.Message}");
                throw;
            }
            finally
            {
                log.Info($"=====结束更改公网IP：{privateIp}=====");
                log.Save();
            }
        }

        public bool EcsCreateNetworkInterface(string region, string instanceId)
        {
            try
            {
                //查询实例信息
                var instance = plus.DescribeInstanceAttribute(region, instanceId);
                var vswitchId = instance.Body.VpcAttributes.VSwitchId;
                var securityGroupId = instance.Body.SecurityGroupIds.SecurityGroupId;

                //申请弹性网卡
                var response = plus.CreateNetworkInterface(region, vswitchId, securityGroupId);
                string networkInterfaceId = response.Body.NetworkInterfaceId;
                string privateIpAddress = response.Body.PrivateIpAddress;
                if (string.IsNullOrEmpty(networkInterfaceId)) throw new Exception(response.Body.ToString());

                //绑定网卡
                plus.AttachNetworkInterface(region, instanceId, networkInterfaceId);

                //申请并绑定公网IP
                EcsAssociateEipAddress(region, networkInterfaceId, privateIpAddress);
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public List<DescribeNetworkInterfacesResponseBodyNetworkInterfaceSetsNetworkInterfaceSet> DescribeNetworkInterfaces(string region, string instanceId)
        {
            try
            {
                var response = plus.DescribeNetworkInterfaces(region, instanceId);
                var list = response.Body.NetworkInterfaceSets.NetworkInterfaceSet;
                return list;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }


        public bool EcsAssignPrivateIpAddresses(string region, string instanceId, int count, bool isPrimaryNetworkInterface = false)
        {
            try
            {
                //查询实例信息
                var instance = plus.DescribeInstanceAttribute(region, instanceId);
                var vswitchId = instance.Body.VpcAttributes.VSwitchId;
                var securityGroupId = instance.Body.SecurityGroupIds.SecurityGroupId;

                var response = plus.DescribeNetworkInterfaces(region, instanceId);
                foreach (var e in response.Body.NetworkInterfaceSets.NetworkInterfaceSet)
                {
                    string type = isPrimaryNetworkInterface ? "Primary" : "Secondary";
                    if (type.Equals(e.Type))
                    {
                        //var response2 = plus.DescribeNetworkInterfaceAttribute(region, e.NetworkInterfaceId);
                        //var PrivateIpAddressList = response2.Body.PrivateIpSets.PrivateIpSet;

                        //foreach (var privateIp in PrivateIpAddressList)
                        //{
                        //    if (privateIp.Primary == true) continue;
                        //    var privateIpAddress = privateIp.PrivateIpAddress;

                        //    //申请公网ip
                        //    var eip = plus.AllocateEipAddress(region);
                        //    var allocationId = eip.Body.AllocationId;
                        //    string eipAddress = eip.Body.EipAddress;

                        //    //绑定公网ip
                        //    var AssociateEipAddress =
                        //        plus.AssociateEipAddress(
                        //            region, allocationId, e.NetworkInterfaceId, EIPInstanceType.NetworkInterface, privateIpAddress);
                        //}

                        //添加辅助私网
                        var response2 = plus.AssignPrivateIpAddresses(region, e.NetworkInterfaceId, count);
                        var PrivateIpAddressList = response2.Body.AssignedPrivateIpAddressesSet.PrivateIpSet.PrivateIpAddress;

                        foreach (var privateIpAddress in PrivateIpAddressList)
                        {
                            //申请公网ip
                            var eip = plus.AllocateEipAddress(region);
                            var allocationId = eip.Body.AllocationId;
                            string eipAddress = eip.Body.EipAddress;

                            //绑定公网ip
                            var AssociateEipAddress =
                                plus.AssociateEipAddress(region, allocationId, e.NetworkInterfaceId, EIPInstanceType.NetworkInterface, privateIpAddress);
                        }


                        return true;
                    }
                }

                return false;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 申请并绑定公网IP
        /// </summary>
        /// <param name="region"></param>
        /// <param name="instanceId"></param>
        /// <param name="privateIpAddress"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public bool EcsAssociateEipAddress(string region, string networkInterfaceId, string privateIpAddress)
        {
            try
            {
                //申请公网ip
                var eip = plus.AllocateEipAddress(region);
                var allocationId = eip.Body.AllocationId;
                string eipAddress = eip.Body.EipAddress;

                //绑定公网ip
                var AssociateEipAddress =
                    plus.AssociateEipAddress(region, allocationId, networkInterfaceId, EIPInstanceType.NetworkInterface);
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }


        public DescribeEipAddressesResponseBodyEipAddressesEipAddress DescribeEipAddresse(string region, string eipAddress)
        {
            try
            {
                var response = plus.DescribeEipAddresses(region, eipAddress);
                var eip = response?.Body?.EipAddresses?.EipAddress?.FirstOrDefault();
                return eip;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }


        public List<DescribeEipAddressesResponseBodyEipAddressesEipAddress> DescribeEipsAddresse(string region, string eipAddress)
        {
            try
            {
                var response = plus.DescribeEipAddresses(region, eipAddress);
                var eips = response?.Body?.EipAddresses?.EipAddress;
                return eips;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public DescribeNetworkInterfaceAttributeResponseBody DescribeNetworkInterfaceAttribute(string region, string networkInterfaceId)
        {
            try
            {
                var response = plus.DescribeNetworkInterfaceAttribute(region, networkInterfaceId);
                var body = response?.Body;
                return body;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }


        public bool ReleaseEipAddress(string region, string allocationId)
        {
            try
            {
                plus.ReleaseEipAddress(region, allocationId);
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

    }


}

