package service

import (
	"context"
	"errors"
	"fmt"
	v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
	"github.com/go-nunu/nunu-layout-advanced/internal/model"
	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
	"github.com/spf13/cast"
	"gorm.io/gorm"
)

type GatewayGroupService interface {
	GetGatewayGroup(ctx context.Context, id int64) (*model.GatewayGroup, error)
	AddGatewayGroup(ctx context.Context, req v1.AddGateWayGroupRequest) (int, error)
	EditGatewayGroup(ctx context.Context, req v1.AddGateWayGroupAdminRequest) error
	DeleteGatewayGroup(ctx context.Context, id int) error
	GetGatewayGroupByHostId(ctx context.Context, hostId int) (model.GatewayGroup, error)
	GetGatewayGroupList(ctx context.Context,req v1.SearchGatewayGroupParams) (*v1.PaginatedResponse[model.GatewayGroup]	, error)
	AddGatewayGroupAdmin(ctx context.Context,req v1.AddGateWayGroupAdminRequest) error
	EditGatewayGroupAdmin(ctx context.Context, req v1.AddGateWayGroupAdminRequest) error
}
func NewGatewayGroupService(
    service *Service,
    gatewayGroupRepository repository.GatewayGroupRepository,
	required RequiredService,
	parser ParserService,
	request RequestService,
) GatewayGroupService {
	return &gatewayGroupService{
		Service:        service,
		gatewayGroupRepository: gatewayGroupRepository,
		required: required,
		parser: parser,
		request: request,
	}
}

type gatewayGroupService struct {
	*Service
	gatewayGroupRepository repository.GatewayGroupRepository
	required RequiredService
	parser ParserService
	request RequestService
}

func (s *gatewayGroupService) GetGatewayGroup(ctx context.Context, id int64) (*model.GatewayGroup, error) {
	return s.gatewayGroupRepository.GetGatewayGroup(ctx, id)
}

func (s *gatewayGroupService) AddGatewayGroup(ctx context.Context, req v1.AddGateWayGroupRequest) (int, error) {
	formData := map[string]interface{}{
		"name": req.Name,
		"comment": req.Comment,
	}
	respBody, err := s.required.SendForm(ctx, "admin/info/waf_gateway_group/new", "admin/new/waf_gateway_group", formData)
	if err != nil {
		return 0, err
	}
	gateWayGroupIdBase, err := s.parser.GetRuleIdByColumnName(ctx, respBody, req.Name)
	if err != nil {
		return 0, err
	}
	if gateWayGroupIdBase == "" {
		res, err := s.parser.ParseAlert(string(respBody))
		if err != nil {
			return 0, err
		}
		return 0, fmt.Errorf(res)
	}
	gateWayGroupId, err := cast.ToIntE(gateWayGroupIdBase)
	if err != nil {
		return 0,  err
	}
	return gateWayGroupId, nil
}

func (s *gatewayGroupService) GetGatewayGroupByHostId(ctx context.Context, hostId int) (model.GatewayGroup, error) {
	res, err := s.gatewayGroupRepository.GetGatewayGroupByHostId(ctx, int64(hostId))
	if err != nil {
		return model.GatewayGroup{}, err
	}
	return *res, nil
}

func (s *gatewayGroupService) EditGatewayGroup(ctx context.Context, req v1.AddGateWayGroupAdminRequest) error {
	if err := s.gatewayGroupRepository.EditGatewayGroup(ctx,  &model.GatewayGroup{
		Id: req.Id,
		Name: req.Name,
		Comment: req.Comment,
		HostId: req.HostId,
		BanUdp: req.BanUdp,
		BanOverseas: req.BanOverseas,
		Operator: req.Operator,
	}); err != nil {
		return err
	}
	return nil

}

func (s *gatewayGroupService) DeleteGatewayGroup(ctx context.Context, id int) error {
	if err := s.gatewayGroupRepository.DeleteGatewayGroup(ctx, id); err != nil {
		return err
	}
	return nil

}
func (s *gatewayGroupService) GetGatewayGroupList(ctx context.Context,req v1.SearchGatewayGroupParams) (*v1.PaginatedResponse[model.GatewayGroup], error) {
	res, err := s.gatewayGroupRepository.GetGatewayGroupList(ctx, req)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, v1.ErrNotFound
		}
		return nil, err
	}
	return res, nil
}

func (s *gatewayGroupService) AddGatewayGroupAdmin(ctx context.Context,req v1.AddGateWayGroupAdminRequest) error {
	if err := s.gatewayGroupRepository.AddGatewayGroup(ctx, &model.GatewayGroup{
		Name: req.Name,
		Comment: req.Comment,
		HostId: req.HostId,
		BanUdp: req.BanUdp,
		BanOverseas: req.BanOverseas,
		Operator: req.Operator,
	}); err != nil {
		return err
	}
	return nil

}

func (s *gatewayGroupService) EditGatewayGroupAdmin(ctx context.Context, req v1.AddGateWayGroupAdminRequest) error {
	if err := s.gatewayGroupRepository.EditGatewayGroupById(ctx,  &model.GatewayGroup{
		Id: req.Id,
		Name: req.Name,
		Comment: req.Comment,
		HostId: req.HostId,
		BanUdp: req.BanUdp,
		BanOverseas: req.BanOverseas,
		Operator: req.Operator,
	}); err != nil {
		return err
	}
	return nil

}