package service

import (
	"context"
	"errors"
	"github.com/go-nunu/nunu-layout-advanced/internal/model"
	"github.com/go-nunu/nunu-layout-advanced/internal/repository"

	"gorm.io/gorm"
	"time"
)

type GameShieldPublicIpService interface {
	GetGameShieldPublicIp(ctx context.Context, id int64) (*model.GameShieldPublicIp, error)
	GetGameShieldPublicUserIp(ctx context.Context, uid int) (string, error)
	GetGameShieldPublicUserIpByNew(ctx context.Context) (model.GameShieldPublicIp, error)
	UpdateGameShieldPublicUserIp(ctx context.Context, uid int, updateTime string) error

	GetUserIp(ctx context.Context, uid int) (string, error)
}

func NewGameShieldPublicIpService(
	service *Service,
	gameShieldPublicIpRepository repository.GameShieldPublicIpRepository,
	gameShieldUserIpRepository repository.GameShieldUserIpRepository,
) GameShieldPublicIpService {
	return &gameShieldPublicIpService{
		Service:                      service,
		gameShieldPublicIpRepository: gameShieldPublicIpRepository,
		gameShieldUserIpRepository:   gameShieldUserIpRepository,
	}
}

type gameShieldPublicIpService struct {
	*Service
	gameShieldPublicIpRepository repository.GameShieldPublicIpRepository
	gameShieldUserIpRepository   repository.GameShieldUserIpRepository
}

func (s *gameShieldPublicIpService) GetGameShieldPublicIp(ctx context.Context, id int64) (*model.GameShieldPublicIp, error) {
	return s.gameShieldPublicIpRepository.GetGameShieldPublicIp(ctx, id)
}

func (s *gameShieldPublicIpService) GetGameShieldPublicUserIp(ctx context.Context, uid int) (string, error) {
	ipId, err := s.gameShieldUserIpRepository.GetGameShieldUserIpByUid(ctx, int64(uid))
	if err != nil {
		return "", err
	}
	if ipId == 0 {
		return "", gorm.ErrRecordNotFound
	}
	ip, err := s.gameShieldPublicIpRepository.GetGameShieldPublicUserIp(ctx, ipId)
	if err != nil {
		return "", err
	}
	return ip, nil
}

func (s *gameShieldPublicIpService) GetGameShieldPublicUserIpByNew(ctx context.Context) (model.GameShieldPublicIp, error) {
	res, err := s.gameShieldPublicIpRepository.GetGameShieldPublicUserIpByNew(ctx)
	if err != nil {
		return model.GameShieldPublicIp{}, err
	}
	return res, nil
}

func (s *gameShieldPublicIpService) UpdateGameShieldPublicUserIp(ctx context.Context, id int, updateTime string) error {
	if err := s.gameShieldPublicIpRepository.UpdateGameShieldPublicUserIp(ctx, id, updateTime); err != nil {
		return err
	}
	return nil
}

func (s *gameShieldPublicIpService) GetUserIp(ctx context.Context, uid int) (string, error) {
	var ip string

	ip, err := s.GetGameShieldPublicUserIp(ctx, uid)
	if err == nil {
		return ip, nil
	}
	var ipId int
	// 如果不是记录未找到，直接返回错误
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		return "", err
	}

	// 分配新 IP（可能失败）
	res, err := s.GetGameShieldPublicUserIpByNew(ctx)
	if err != nil {
		return "", err
	}
	ip = res.Ip
	ipId = res.Id
	if len(ip) == 0 {
		res, err := s.gameShieldPublicIpRepository.GetGameShieldPublicUserIpByOld(ctx)
		if err != nil {
			return "", err
		}
		ip = res.Ip
		ipId = res.Id
	}
	// 更新绑定关系
	var updateTime string
	updateTime = time.Now().Format("2006-01-02 15:04:05")
	if err := s.UpdateGameShieldPublicUserIp(ctx, ipId, updateTime); err != nil {
		return "", err
	}
	if err := s.gameShieldUserIpRepository.AddGameShieldUserIp(ctx, &model.GameShieldUserIp{Uid: uid, IpId: ipId}); err != nil {
		return "", err
	}
	return ip, nil
}
