package svc

import (
	"backend/internal/config"
	"backend/internal/middleware"
	errs "backend/pkg/library/errors"
	"backend/pkg/library/errors/code"
	"context"

	"github.com/zeromicro/go-zero/core/logx"

	chatUC "backend/pkg/chat/domain/usecase"
	fileStorageUC "backend/pkg/fileStorage/domain/usecase"
	vi "backend/pkg/library/validator"
	memberUC "backend/pkg/member/domain/usecase"
	deliveryUC "backend/pkg/notification/domain/usecase"
	tokenUC "backend/pkg/permission/domain/usecase"

	"github.com/zeromicro/go-zero/core/stores/redis"
	"github.com/zeromicro/go-zero/rest"
)

type ServiceContext struct {
	Config         config.Config
	AuthMiddleware rest.Middleware
	AccountUC      memberUC.AccountUseCase
	Validate       vi.Validate
	TokenUC        tokenUC.TokenUseCase
	PermissionUC   tokenUC.PermissionUseCase
	RoleUC         tokenUC.RoleUseCase
	RolePermission tokenUC.RolePermissionUseCase
	UserRoleUC     tokenUC.UserRoleUseCase
	DeliveryUC     deliveryUC.DeliveryUseCase
	FileStorageUC  fileStorageUC.FileStorageUseCase
	MessageUC      chatUC.MessageUseCase
	Redis          *redis.Redis
	Logger         errs.Logger
}

func NewServiceContext(c config.Config) *ServiceContext {
	rds, err := redis.NewRedis(c.RedisConf)
	if err != nil {
		panic(err)
	}
	errs.Scope = code.Gateway

	rp := NewPermissionUC(&c)
	tkUC := NewTokenUC(&c, rds)
	lgr := MustLogger(logx.WithContext(context.Background()))

	return &ServiceContext{
		Config: c,
		AuthMiddleware: middleware.NewAuthMiddleware(middleware.AuthMiddlewareParam{
			TokenSec:     c.Token.AccessSecret,
			TokenUseCase: tkUC,
		}).Handle,
		AccountUC:      NewAccountUC(&c, rds),
		Validate:       vi.MustValidator(),
		TokenUC:        tkUC,
		PermissionUC:   rp.PermissionUC,
		RoleUC:         rp.RoleUC,
		RolePermission: rp.RolePermission,
		UserRoleUC:     rp.UserRole,
		Redis:          rds,
		DeliveryUC:     MustDeliveryUseCase(&c, lgr),
		FileStorageUC:  MustS3Storage(&c, lgr),
		MessageUC:      MustMessageUseCase(&c, lgr),
		Logger:         lgr,
	}
}
