package privatelinkservice

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/log"
	regionalapiv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/common/clustercli"
	bizerr "github.com/tidbcloud/infra-provider/regional-server/pkg/common/errors"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/common/message"
	rsconfig "github.com/tidbcloud/infra-provider/regional-server/pkg/config"
	resapproute "github.com/tidbcloud/infra-provider/regional-server/pkg/resourcemanager/approute"
	respls "github.com/tidbcloud/infra-provider/regional-server/pkg/resourcemanager/privatelinkservice"
	resplsm "github.com/tidbcloud/infra-provider/regional-server/pkg/resourcemanager/privatelinkservicemigration"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/router/interceptor"
	serpls "github.com/tidbcloud/infra-provider/regional-server/pkg/service/privatelinkservicemigration"
	"go.uber.org/zap"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

type PrivateLinkServiceMigrationHandler struct {
	plsmsvc *serpls.PrivateLinkServiceMigrationService
	config  rsconfig.RootConfig
}

func NewPrivateLinkServiceMigrationHandler(cli client.Client, clusterCli clustercli.ClusterClient, config rsconfig.RootConfig) *PrivateLinkServiceMigrationHandler {
	return &PrivateLinkServiceMigrationHandler{
		plsmsvc: serpls.NewPrivateLinkServiceMigrationService(
			resplsm.NewPrivateLinkServiceMigrationReaderWriter(cli),
			respls.NewPrivateLinkServiceReaderWriter(cli),
			resapproute.NewAPPRouteReader(cli),
			clusterCli,
			config,
		),
		config: config,
	}
}

func (r *PrivateLinkServiceMigrationHandler) CreatePrivateLinkServiceMigration(c *gin.Context) {
	req := &regionalapiv1.CreatePrivateLinkServiceMigrationRequest{}
	if ok := interceptor.HandleJsonPbRequestFromBody(c, req); !ok {
		log.Error("failed to handle json pb request from body")
		return
	}
	if err := (&message.CreatePrivateLinkServiceMigrationReqValidatable{CreatePrivateLinkServiceMigrationRequest: req}).Validate(); err != nil {
		log.Error("invalid request", zap.Any("req", req), zap.Error(err))
		interceptor.Fail(c, bizerr.New(bizerr.ParameterInvalid, err.Error()))
		return
	}
	resp, err := r.plsmsvc.CreatePrivateLinkServiceMigration(c, req)
	if err != nil {
		log.Error("failed to create private link service migration", zap.Any("req", req), zap.Error(err))
		interceptor.Fail(c, err)
		return
	} else {
		interceptor.SucceedPb(c, http.StatusAccepted, resp)
	}
}

func (r *PrivateLinkServiceMigrationHandler) GetPrivateLinkServiceMigration(c *gin.Context) {
	req := &regionalapiv1.GetPrivateLinkServiceMigrationRequest{
		Id: c.Param("privateLinkServiceMigrationId"),
	}
	if err := (&message.GetPrivateLinkServiceMigrationReqValidatable{GetPrivateLinkServiceMigrationRequest: req}).Validate(); err != nil {
		log.Error("invalid request", zap.Any("req", req), zap.Error(err))
		interceptor.Fail(c, bizerr.New(bizerr.ParameterInvalid, err.Error()))
		return
	}
	resp, err := r.plsmsvc.GetPrivateLinkServiceMigration(c, req)
	if err != nil {
		log.Error("failed to get private link service migration", zap.Any("req", req), zap.Error(err))
		interceptor.Fail(c, err)
		return
	} else {
		interceptor.SucceedPb(c, http.StatusOK, resp)
	}
}

func (r *PrivateLinkServiceMigrationHandler) ListPrivateLinkServiceMigrations(c *gin.Context) {
	req := &regionalapiv1.ListPrivateLinkServiceMigrationsRequest{
		ProjectId: c.Query("projectId"),
	}
	if err := (&message.ListPrivateLinkServiceMigrationsReqValidatable{ListPrivateLinkServiceMigrationsRequest: req}).Validate(); err != nil {
		log.Error("invalid request", zap.Any("req", req), zap.Error(err))
		interceptor.Fail(c, bizerr.New(bizerr.ParameterInvalid, err.Error()))
		return
	}
	resp, err := r.plsmsvc.ListPrivateLinkServiceMigrations(c, req)
	if err != nil {
		log.Error("failed to list private link service migrations", zap.Any("req", req), zap.Error(err))
		interceptor.Fail(c, err)
		return
	} else {
		interceptor.SucceedPb(c, http.StatusOK, resp)
	}
}
