package handlers

import (
	"context"

	dbgen "Yimaru-Backend/gen/db"
	"Yimaru-Backend/internal/config"
	"Yimaru-Backend/internal/domain"
	activitylogservice "Yimaru-Backend/internal/services/activity_log"
	"Yimaru-Backend/internal/services/arifpay"
	"Yimaru-Backend/internal/services/assessment"
	"Yimaru-Backend/internal/services/authentication"
	course_management "Yimaru-Backend/internal/services/course_management"
	issuereporting "Yimaru-Backend/internal/services/issue_reporting"
	notificationservice "Yimaru-Backend/internal/services/notification"
	"Yimaru-Backend/internal/services/questions"
	"Yimaru-Backend/internal/services/recommendation"
	"Yimaru-Backend/internal/services/subscriptions"
	"Yimaru-Backend/internal/services/team"
	vimeoservice "Yimaru-Backend/internal/services/vimeo"

	// referralservice "Yimaru-Backend/internal/services/referal"

	"Yimaru-Backend/internal/services/settings"

	"Yimaru-Backend/internal/services/transaction"
	"Yimaru-Backend/internal/services/user"
	jwtutil "Yimaru-Backend/internal/web_server/jwt"
	customvalidator "Yimaru-Backend/internal/web_server/validator"
	"log/slog"

	"go.uber.org/zap"
)

type Handler struct {
	assessmentSvc     *assessment.Service
	courseMgmtSvc     *course_management.Service
	questionsSvc      *questions.Service
	subscriptionsSvc  *subscriptions.Service
	arifpaySvc        *arifpay.ArifpayService
	logger            *slog.Logger
	settingSvc        *settings.Service
	notificationSvc   *notificationservice.Service
	userSvc           *user.Service
	transactionSvc    *transaction.Service
	recommendationSvc recommendation.RecommendationService
	authSvc           *authentication.Service
	vimeoSvc          *vimeoservice.Service
	teamSvc           *team.Service
	activityLogSvc    *activitylogservice.Service
	issueReportingSvc *issuereporting.Service
	jwtConfig         jwtutil.JwtConfig
	validator         *customvalidator.CustomValidator
	Cfg               *config.Config
	mongoLoggerSvc    *zap.Logger
	analyticsDB       *dbgen.Queries
}

func New(
	assessmentSvc *assessment.Service,
	courseMgmtSvc *course_management.Service,
	questionsSvc *questions.Service,
	subscriptionsSvc *subscriptions.Service,
	arifpaySvc *arifpay.ArifpayService,
	logger *slog.Logger,
	settingSvc *settings.Service,
	notificationSvc *notificationservice.Service,
	validator *customvalidator.CustomValidator,
	recommendationSvc recommendation.RecommendationService,
	userSvc *user.Service,
	transactionSvc *transaction.Service,
	authSvc *authentication.Service,
	vimeoSvc *vimeoservice.Service,
	teamSvc *team.Service,
	activityLogSvc *activitylogservice.Service,
	issueReportingSvc *issuereporting.Service,
	jwtConfig jwtutil.JwtConfig,
	cfg *config.Config,
	mongoLoggerSvc *zap.Logger,
	analyticsDB *dbgen.Queries,
) *Handler {
	return &Handler{
		assessmentSvc:     assessmentSvc,
		courseMgmtSvc:     courseMgmtSvc,
		questionsSvc:      questionsSvc,
		subscriptionsSvc:  subscriptionsSvc,
		arifpaySvc:        arifpaySvc,
		logger:            logger,
		settingSvc:        settingSvc,
		notificationSvc:   notificationSvc,
		validator:         validator,
		userSvc:           userSvc,
		transactionSvc:    transactionSvc,
		recommendationSvc: recommendationSvc,
		authSvc:           authSvc,
		vimeoSvc:          vimeoSvc,
		teamSvc:           teamSvc,
		activityLogSvc:    activityLogSvc,
		issueReportingSvc: issueReportingSvc,
		jwtConfig:         jwtConfig,
		Cfg:               cfg,
		mongoLoggerSvc:    mongoLoggerSvc,
		analyticsDB:       analyticsDB,
	}
}

func (h *Handler) sendInAppNotification(recipientID int64, notifType domain.NotificationType, headline, message string) {
	go func() {
		notification := &domain.Notification{
			RecipientID:     recipientID,
			Type:            notifType,
			Level:           domain.NotificationLevelInfo,
			DeliveryChannel: domain.DeliveryChannelInApp,
			DeliveryStatus:  domain.DeliveryStatusPending,
			IsRead:          false,
			Payload: domain.NotificationPayload{
				Headline: headline,
				Message:  message,
			},
		}
		_ = h.notificationSvc.SendNotification(context.Background(), notification)
	}()
}
