package service

import (
	"context"
	"fmt"
	"github.com/go-nunu/nunu-layout-advanced/internal/model"
	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
	"strconv"
	"strings"
)

type GameShieldSdkIpService interface {
	GetGameShieldSdkIp(ctx context.Context, id int64) (*model.GameShieldSdkIp, error)
	GenerateMultipleLoopbackIps(ctx context.Context, uid int, hostId int, count ...int) error
}

func NewGameShieldSdkIpService(
	service *Service,
	gameShieldSdkIpRepository repository.GameShieldSdkIpRepository,
) GameShieldSdkIpService {
	return &gameShieldSdkIpService{
		Service:                   service,
		gameShieldSdkIpRepository: gameShieldSdkIpRepository,
	}
}

type gameShieldSdkIpService struct {
	*Service
	gameShieldSdkIpRepository repository.GameShieldSdkIpRepository
}

func (s *gameShieldSdkIpService) GetGameShieldSdkIp(ctx context.Context, id int64) (*model.GameShieldSdkIp, error) {
	return s.gameShieldSdkIpRepository.GetGameShieldSdkIp(ctx, id)
}

// GenerateMultipleLoopbackIps 生成多个唯一127.0.0.0/8范围IP地址
// count 指定需要生成的IP地址数量，默认为10
// 返回生成的唯一IP地址数组和可能的错误
// GenerateMultipleLoopbackIps 生成并保存多个唯一127.0.0.0/8范围IP地址到数据库
// uid 用户ID
// hostId 实例ID
// count 指定需要生成的IP地址数量，默认为10
// 返回生成并保存的唯一IP地址数组和可能的错误
func (s *gameShieldSdkIpService) GenerateMultipleLoopbackIps(ctx context.Context, uid int, hostId int, count ...int) error {
	requiredCount := 10
	if len(count) > 0 && count[0] > 0 {
		requiredCount = count[0]
	}
	haveCount, err := s.gameShieldSdkIpRepository.GetGameShieldSdkIpCountByHostId(ctx, hostId)
	if err != nil {
		return err
	}
	if int(haveCount) >= requiredCount {
		return nil
	}
	// 从数据库获取最新的一条IP记录
	latestIp, err := s.gameShieldSdkIpRepository.GetGameShieldSdkIpNewByHostId(ctx, hostId)
	if err != nil {
		// 如果没有记录，默认从127.0.0.2开始（避免使用127.0.0.1）
		latestIp = "127.0.0.1"
	}

	// 解析IP成四个段
	ipParts := strings.Split(latestIp, ".")
	if len(ipParts) != 4 {
		return fmt.Errorf("无效的IP格式: %s", latestIp)
	}

	// 将IP段转换为整数
	a, err1 := strconv.Atoi(ipParts[0])
	b, err2 := strconv.Atoi(ipParts[1])
	c, err3 := strconv.Atoi(ipParts[2])
	d, err4 := strconv.Atoi(ipParts[3])

	if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
		return fmt.Errorf("IP段转换失败: %s", latestIp)
	}

	// 确保第一段是127（保持在回环地址范围内）
	if a != 127 {
		a = 127
		b, c, d = 0, 0, 1 // 重置为127.0.0.1
	}

	// 从最新IP的下一个地址开始
	d++
	if d > 254 {
		d = 0
		c++
		if c > 255 {
			c = 0
			b++
			if b > 255 {
				return fmt.Errorf("IP地址池已耗尽")
			}
		}
	}

	// 收集生成的唯一IP
	result := make([]string, 0, requiredCount)
	attempts := 0
	maxAttempts := 10000 // 防止无限循环

	for len(result) < requiredCount && attempts < maxAttempts {
		currentIp := fmt.Sprintf("127.%d.%d.%d", b, c, d)

		// 尝试将IP保存到数据库
		err := s.gameShieldSdkIpRepository.AddGameShieldSdkIp(ctx, &model.GameShieldSdkIp{
			HostId: hostId,
			Uid:    uid,
			SdkIp:  currentIp,
		})
		if err == nil {
			// 保存成功，添加到结果列表
			result = append(result, currentIp)
		} else {
			// 如果是因为IP已存在导致的错误，我们忽略并继续
			// 其他错误则返回
			if !strings.Contains(err.Error(), "unique_sdk_ip") {
				return fmt.Errorf("保存IP到数据库失败: %w", err)
			}
			// IP已存在，继续尝试下一个
		}

		// 递增IP地址
		d++
		if d > 255 {
			d = 0
			c++
			if c > 255 {
				c = 0
				b++
				if b > 255 {
					break
				}
			}
		}

		attempts++
	}

	if len(result) < requiredCount {
		return fmt.Errorf("无法生成足够的唯一IP地址，地址池可能已耗尽，仅生成了%d个", len(result))
	}

	return nil
}
