package privilege

import (
	userv1 "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/api/core-server/user/v1"
	"github.com/tidbcloud/devops/pkg/infra/clients/larkcli"
	"github.com/tidbcloud/devops/pkg/infra/config"
	"github.com/tidbcloud/devops/pkg/service"
	apprapi "github.com/tidbcloud/devops/pkg/service/approval/api"
	"github.com/tidbcloud/devops/pkg/service/privilege/api"
	"github.com/tidbcloud/devops/pkg/service/privilege/repo"

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

type ServiceParam struct {
	dig.In

	Conf       *config.RootConfig
	DBProvider db.TransProvider
	User       userv1.UserServiceClient
	Approval   apprapi.ApprovalServiceAPI
	LarkClient *larkcli.LarkClient
}

type ServiceResult struct {
	dig.Out

	API     api.PrivilegeServiceAPI
	Service service.Service `group:"service"`
}

type svc struct {
	*service.JobService

	conf    *config.PrivilegeServiceConfig
	dbp     db.TransProvider
	userSvc userv1.UserServiceClient
	apprSvc apprapi.ApprovalServiceAPI
	larkCli *larkcli.LarkClient
	repo    repo.Repo

	syncPrivilegeCh chan uint64
}

func NewService(p ServiceParam) (ServiceResult, error) {
	base := service.NewJobService("PrivilegeService", service.WithDummy(p.Conf.Services.Privilege.Dummy))
	if p.Conf.Services.Privilege.Dummy {
		return ServiceResult{
			API:     &api.DummyPrivilegeServiceAPI{},
			Service: base,
		}, nil
	}

	s := &svc{
		JobService: base,

		conf:            &p.Conf.Services.Privilege,
		dbp:             p.DBProvider,
		userSvc:         p.User,
		apprSvc:         p.Approval,
		larkCli:         p.LarkClient,
		repo:            repo.NewRepo(p.DBProvider),
		syncPrivilegeCh: make(chan uint64, 10),
	}

	if !s.conf.DisableCron {
		s.AddJob(
			service.NewConstantCronJob("WatchPrivileges", *s.conf.WatchPrivilegesInterval, s.WatchPrivileges),
			service.NewConstantCronJob("WatchPrivilegesSlowly", *s.conf.WatchPrivilegesSlowlyInterval, s.WatchPrivilegesSlowly),
			// service.NewCronJob("NotifyPrivilegeWillExpireDaily", "0 0 * * *", s.NotifyPrivilegeExpired),
			service.NewEventJob("SyncPrivilege", s.syncPrivilegeCh, s.SyncPrivilege),
		)
	}

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