package refresh_wc

import (
	"amocrm/internal/models"
	"amocrm/pkg/amoClient"
	"amocrm/pkg/timer"
	"context"
	"go.uber.org/zap"
	"gitea.pena/SQuiz/common/dal"
	"gitea.pena/SQuiz/common/model"
	"time"
)

type Deps struct {
	AmoClient *amoClient.Amo
	Repo      *dal.AmoDal
	Logger    *zap.Logger
}

type WebHookUpdater struct {
	amoClient *amoClient.Amo
	repo      *dal.AmoDal
	logger    *zap.Logger
}

func NewRefreshWC(deps Deps) *WebHookUpdater {
	return &WebHookUpdater{
		amoClient: deps.AmoClient,
		repo:      deps.Repo,
		logger:    deps.Logger,
	}
}

func (wc *WebHookUpdater) Start(ctx context.Context) {
	nextStart := timer.CalculateTime(3)
	ticker := time.NewTicker(time.Nanosecond * time.Duration(nextStart))
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			wc.processTasks(ctx)
			nextStart = timer.CalculateTime(3)
			ticker.Reset(time.Nanosecond * time.Duration(nextStart))

		case <-ctx.Done():
			return
		}
	}
}

// todo если так нормально будет, то предлагаю батчами сделать, батч на 1000 к примеру,
// делим количество всего токенов на  размер батча чтобы было без остатка и строим вейт группу вокруг этого
func (wc *WebHookUpdater) processTasks(ctx context.Context) {
	currentTokens, err := wc.repo.AmoRepo.GetAllTokens(ctx)
	if err != nil {
		wc.logger.Error("Failed to get all tokens", zap.Error(err))
		return
	}

	for _, token := range currentTokens {
		user, err := wc.repo.AmoRepo.GetCurrentAccount(ctx, token.AccountID)
		if err != nil {
			wc.logger.Error("error getting account by id", zap.Error(err))
			continue
		}
		req := models.UpdateWebHookReq{
			GrantType:    "refresh_token",
			RefreshToken: token.RefreshToken,
		}

		resp, err := wc.amoClient.CreateWebHook(&req, user.Subdomain)
		if err != nil {
			wc.logger.Error("error create webhook", zap.Error(err))
			continue
		}

		err = wc.repo.AmoRepo.WebhookUpdate(ctx, model.Token{
			AccountID:    token.AccountID,
			RefreshToken: resp.RefreshToken,
			AccessToken:  resp.AccessToken,
			Expiration:   time.Now().Unix() + resp.ExpiresIn,
			CreatedAt:    time.Now().Unix(),
		})
		if err != nil {
			wc.logger.Error("error update token in db", zap.Error(err))
			continue
		}
	}
}

func (wc *WebHookUpdater) Stop(_ context.Context) error {
	return nil
}
