package grpc

import (
	"context"
	"time"

	activityv1 "hyapp.local/api/proto/activity/v1"
	"hyapp/pkg/appcode"
	"hyapp/pkg/xerr"
	messageservice "hyapp/services/activity-service/internal/service/message"
)

// CronServer exposes activity-service owned background batches to cron-service.
type CronServer struct {
	activityv1.UnimplementedActivityCronServiceServer

	message *messageservice.Service
}

// NewCronServer creates the internal cron adapter without exposing message storage.
func NewCronServer(messageSvc *messageservice.Service) *CronServer {
	return &CronServer{message: messageSvc}
}

// ProcessMessageFanoutBatch claims and processes one message fanout page.
func (s *CronServer) ProcessMessageFanoutBatch(ctx context.Context, req *activityv1.CronBatchRequest) (*activityv1.CronBatchResponse, error) {
	ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
	if s.message == nil {
		return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "message service is not configured"))
	}
	processed, err := s.message.ProcessNextFanoutJob(ctx, messageservice.FanoutWorkerOptions{
		WorkerID:  req.GetWorkerId(),
		BatchSize: int(req.GetBatchSize()),
		LockTTL:   durationFromMillis(req.GetLockTtlMs()),
	})
	if err != nil {
		return nil, xerr.ToGRPCError(err)
	}
	if !processed {
		return &activityv1.CronBatchResponse{}, nil
	}
	return &activityv1.CronBatchResponse{
		ClaimedCount:   1,
		ProcessedCount: 1,
		SuccessCount:   1,
		HasMore:        true,
	}, nil
}

func durationFromMillis(value int64) time.Duration {
	if value <= 0 {
		return 0
	}
	return time.Duration(value) * time.Millisecond
}
