package controlplane

import (
	"time"

	cp "github.com/tidbcloud/devops/entity/controlplane"
	"github.com/tidbcloud/devops/pkg/infra/clients/githubcli"
	"github.com/tidbcloud/devops/pkg/infra/eventbus"
	"github.com/tidbcloud/devops/pkg/service"
	apprsvcapi "github.com/tidbcloud/devops/pkg/service/approval/api"
	depsvcapi "github.com/tidbcloud/devops/pkg/service/controlplane/api"
	"github.com/tidbcloud/devops/pkg/service/controlplane/repo"

	"github.com/go-logr/logr"
	"github.com/tidbcloud/pkgv2/db"
	"go.uber.org/dig"
)

const (
	groupKey                = "devops_deployment_service"
	pollWorkflowRunInterval = 30 * time.Second
)

var _ depsvcapi.DeploymentServiceAPI = &svc{}

type ServiceParam struct {
	dig.In

	Logger          logr.Logger
	EventBus        *eventbus.EventBus
	DBProvider      db.TransProvider
	GithubActionCli githubcli.Client
	Approval        apprsvcapi.ApprovalServiceAPI
}

type ServiceResult struct {
	dig.Out

	API     depsvcapi.DeploymentServiceAPI
	Service service.Service `group:"service"`
}

type svc struct {
	*service.JobService

	logger   logr.Logger
	eventbus *eventbus.EventBus
	dbp      db.Transactioner
	ghCli    githubcli.Client
	apprSvc  apprsvcapi.ApprovalServiceAPI
	repo     repo.Repo
}

func NewService(p ServiceParam) (ServiceResult, error) {
	driver := repo.NewDeploymentDriver(p.DBProvider)
	s := &svc{
		JobService: service.NewJobService("DeploymentService"),

		logger:   p.Logger.WithName("DeploymentService"),
		eventbus: p.EventBus,
		dbp:      p.DBProvider,
		ghCli:    p.GithubActionCli,
		apprSvc:  p.Approval,
		repo:     repo.NewRepo(driver),
	}

	s.AddJob(
		service.NewConstantCronJob("PollWorkflowRuns", pollWorkflowRunInterval, s.PollWorkflowRuns),
	)

	s.eventbus.ApprovalEvent.Subscribe(groupKey, s.HandleApprovalEvent)

	return ServiceResult{API: s, Service: s}, nil
}

func scenarioToApprovalName(scenario cp.Scenario) string {
	return "deployment/" + string(scenario)
}
