package admin

import (
	"context"
	"encoding/json"
	"fmt"
	v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
	v1admin "github.com/go-nunu/nunu-layout-advanced/api/v1/admin"
	"github.com/go-nunu/nunu-layout-advanced/internal/model"
	"github.com/go-nunu/nunu-layout-advanced/internal/repository/admin"
	"github.com/go-nunu/nunu-layout-advanced/internal/service"
	"github.com/hashicorp/go-multierror"
	"github.com/spf13/viper"
)

type GatewayIpAdminService interface {
	GetGatewayIpAdmin(ctx context.Context, id int64) (*model.Gatewayip, error)
	GetGatewayGroupIpList(ctx context.Context,req v1admin.SearchGatewayIpParams) (*v1.PaginatedResponse[model.Gatewayip], error)
	AddGatewayIp(ctx context.Context,req model.Gatewayip) error
	EditGatewayIp(ctx context.Context,req model.Gatewayip) error
	DeleteGatewayIp(ctx context.Context,id int64) error
	DeleteGatewayIps(ctx context.Context, ids []int64) error
}
func NewGatewayIpAdminService(
    service *service.Service,
    gatewayIpAdminRepository admin.GatewayIpAdminRepository,
	config *viper.Viper,
	request service.RequestService,
) GatewayIpAdminService {
	return &gatewayIpAdminService{
		Service:        service,
		gatewayIpAdminRepository: gatewayIpAdminRepository,
		request: request,
		config: config,
	}
}

type gatewayIpAdminService struct {
	*service.Service
	gatewayIpAdminRepository admin.GatewayIpAdminRepository
	config                    *viper.Viper
	request                   service.RequestService
}

func (s *gatewayIpAdminService) sendIp(ctx context.Context, ip string, action string,nodeArea string) error  {


	serverIps := s.config.GetStringSlice("addServerIp." + nodeArea)

	for _, serverIp := range serverIps {

		apiUrl := "http://" + serverIp + ":3075/" + action

		formData := map[string]interface{}{
			"ip": ip,
		}
		resBody, err := s.request.Request(ctx, formData, apiUrl, "", "")
		if err != nil {
			return err
		}
		var res v1.GeneralResponse[any]
		err = json.Unmarshal(resBody, &res)
		if err != nil {
			return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
		}
		if res.Code != 0 {
			return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
		}
	}

	return nil

}
func (s *gatewayIpAdminService) GetGatewayIpAdmin(ctx context.Context, id int64) (*model.Gatewayip, error) {
	return s.gatewayIpAdminRepository.GetGatewayIpAdmin(ctx, id)
}

func (s *gatewayIpAdminService) GetGatewayGroupIpList(ctx context.Context,req v1admin.SearchGatewayIpParams) (*v1.PaginatedResponse[model.Gatewayip], error) {
	return s.gatewayIpAdminRepository.GetGatewayGroupIpList(ctx,req)
}

func (s *gatewayIpAdminService) AddGatewayIp(ctx context.Context,req model.Gatewayip) error {


	// 启动网关组IP
	if req.NodeArea != "" {
		err := s.sendIp(ctx,req.Ip,"addIp",req.NodeArea)
		if err != nil {
			return err
		}
	}

	return s.gatewayIpAdminRepository.AddGatewayIp(ctx,req)
}

func (s *gatewayIpAdminService) EditGatewayIp(ctx context.Context,req model.Gatewayip) error {
	oldData, err := s.GetGatewayIpAdmin(ctx, int64(req.Id))
	if err != nil {
		return err
	}
	if oldData.Ip != req.Ip  || oldData.NodeArea != "" || req.NodeArea != "" {
		// 启动网关组IP
		err := s.sendIp(ctx,oldData.Ip,"deleteIp",oldData.NodeArea)
		if err != nil {
			return err
		}

		err = s.sendIp(ctx,req.Ip,"addIp",req.NodeArea)
		if err != nil {
			return err
		}
	}

	return s.gatewayIpAdminRepository.EditGatewayIp(ctx,req)
}

func (s *gatewayIpAdminService) DeleteGatewayIp(ctx context.Context,id int64) error {
	oldData, err := s.GetGatewayIpAdmin(ctx, id)
	if err != nil {
		return err
	}
	if oldData.HostId != 0 {
		return fmt.Errorf("该IP已被绑定,无法删除")
	}

	// 启动网关组IP
	if oldData.NodeArea != "" {
		err := s.sendIp(ctx,oldData.Ip,"deleteIp",oldData.NodeArea)
		if err != nil {
			return err
		}
	}
	return s.gatewayIpAdminRepository.DeleteGatewayIp(ctx,id)
}

func (s *gatewayIpAdminService) DeleteGatewayIps(ctx context.Context, ids []int64) error {

	var allErrors *multierror.Error

	for _, id := range ids {
		oldData, err := s.GetGatewayIpAdmin(ctx, id)
		if err != nil {
			return err
		}

		if oldData.HostId != 0 {
			return fmt.Errorf("该IP已被绑定,无法删除")
		}

		// 启动网关组IP
		if oldData.NodeArea != "" {
			err := s.sendIp(ctx,oldData.Ip,"deleteIp",oldData.NodeArea)
			if err != nil {
				allErrors = multierror.Append(allErrors, err)
			}
		}



	}

	if allErrors != nil {
		return allErrors.ErrorOrNil()
	}


	return s.gatewayIpAdminRepository.DeleteGatewayIps(ctx,ids)
}