package v1

import (
	"context"

	"github.com/pingcap-inc/pchub/internal/apiserver/store"
	"github.com/pingcap-inc/pchub/pkg/log"
)

type cronService struct {
	store store.Factory
}

type CronSrv interface {
	SyncBQ(ctx context.Context) error
	SyncDept(ctx context.Context) error
	SyncUser(ctx context.Context) error
	SyncCM(ctx context.Context) error
	CheckBillingAlerts(ctx context.Context) error
	StartSync(ctx context.Context, funcName string)
}

var _ CronSrv = (*cronService)(nil)

func newCronSrv(srv *service) *cronService {
	return &cronService{store: srv.store}
}

//nolint:cyclop // acpetable
func (s *cronService) StartSync(ctx context.Context, funcName string) {
	switch funcName {
	case "billing":
		err := s.CheckBillingAlerts(ctx)
		if err != nil {
			log.L(ctx).Errorf("Error when run check billing-alerts after sync billings: %s", err.Error())
		}
	case "dept":
		err := s.SyncDept(ctx)
		if err != nil {
			log.L(ctx).Errorf("Error when run sync-department task: %s", err.Error())
		}
	case "chat":
		err := s.SyncChat(ctx)
		if err != nil {
			log.L(ctx).Errorf("Error when run sync-chat task: %s", err.Error())
		}
	case "user":
		err := s.SyncUser(ctx)
		if err != nil {
			log.L(ctx).Errorf("Error when run sync-lark-user task: %s", err.Error())
		}
	case "cm":
		err := s.SyncCM(ctx)
		if err != nil {
			log.L(ctx).Errorf("Error when run sync-cloud-member task: %s", err.Error())
		}
	case "all":
		err := s.SyncBQ(ctx)
		if err != nil {
			log.L(ctx).Errorf("Error when run sync-cloud-billing task: %s", err.Error())
		}
		err = s.SyncDept(ctx)
		if err != nil {
			log.L(ctx).Errorf("Error when run sync-department task: %s", err.Error())
		}
		err = s.SyncUser(ctx)
		if err != nil {
			log.L(ctx).Errorf("Error when run sync-lark-user task: %s", err.Error())
		}
		err = s.SyncCM(ctx)
		if err != nil {
			log.L(ctx).Errorf("Error when run sync-cloud-member task: %s", err.Error())
		}
	default:
		log.L(ctx).Errorf("Invalid function name: %s", funcName)
	}
}

func (s *cronService) CheckBillingAlerts(ctx context.Context) error {
	bSrv := billingService{store: s.store}
	err := bSrv.CheckCostAlerts(ctx)
	if err != nil {
		log.L(ctx).Errorf("Error when run check billing-alerts: %s", err.Error())

		return err
	}
	log.L(ctx).Info("Check billing-alerts successfully")

	return nil
}

func (s *cronService) SyncBQ(ctx context.Context) error {
	bSrv := billingService{store: s.store}
	err := bSrv.SyncWithBQ(ctx, false)
	if err != nil {
		log.L(ctx).Errorf("Error when run sync-cloud-billing task: %s", err.Error())

		return err
	}
	log.L(ctx).Info("Sync billing with BQ successfully")

	return nil
}

func (s *cronService) SyncDept(ctx context.Context) error {
	deptSrv := departmentService{store: s.store}
	err := deptSrv.SyncWithLark(ctx)
	if err != nil {
		log.L(ctx).Errorf("Error when run sync-department task: %s", err.Error())

		return err
	}
	log.L(ctx).Info("Sync department with Lark successfully")

	return nil
}

func (s *cronService) SyncChat(ctx context.Context) error {
	chatSrv := larkChatService{store: s.store}
	err := chatSrv.SyncChats(ctx)
	if err != nil {
		log.L(ctx).Errorf("Error when run sync-chat task: %s", err.Error())

		return err
	}
	log.L(ctx).Info("Sync chat with Lark successfully")

	return nil
}

func (s *cronService) SyncUser(ctx context.Context) error {
	userSrv := userService{store: s.store}
	err := userSrv.SyncUsersWithLark(ctx)
	if err != nil {
		log.L(ctx).Errorf("Error when run sync-lark-user task: %s", err.Error())

		return err
	}
	log.L(ctx).Info("Sync user with Lark successfully")

	return nil
}

func (s *cronService) SyncCM(ctx context.Context) error {
	cmSrv := resourceManagerService{store: s.store}
	err := cmSrv.SyncCloudMember(ctx)
	if err != nil {
		log.L(ctx).Errorf("Error when run sync-cloud-member task: %s", err.Error())

		return err
	}
	log.L(ctx).Info("Sync cloud member successfully")

	return nil
}
