package service

import (
	"git.gocasts.ir/ebhomengo/niki/adapter/redis"
	"git.gocasts.ir/ebhomengo/niki/config"
	smscontract "git.gocasts.ir/ebhomengo/niki/contract/sms"
	"git.gocasts.ir/ebhomengo/niki/repository/mysql"
	mysqladdress "git.gocasts.ir/ebhomengo/niki/repository/mysql/address"
	mysqladmin "git.gocasts.ir/ebhomengo/niki/repository/mysql/admin"
	mysqlagent "git.gocasts.ir/ebhomengo/niki/repository/mysql/agent"
	mysqlbenefactor "git.gocasts.ir/ebhomengo/niki/repository/mysql/benefactor"
	mysqlkindbox "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box"
	mysqlkindboxreq "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box_req"
	mysqlrefertime "git.gocasts.ir/ebhomengo/niki/repository/mysql/refer_time"
	redisotp "git.gocasts.ir/ebhomengo/niki/repository/redis/otp"
	adminaddressservice "git.gocasts.ir/ebhomengo/niki/service/admin/address"
	adminservice "git.gocasts.ir/ebhomengo/niki/service/admin/admin"
	adminagentservice "git.gocasts.ir/ebhomengo/niki/service/admin/agent"
	adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
	adminbenefactorservice "git.gocasts.ir/ebhomengo/niki/service/admin/benefactor"
	adminkindboxservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box"
	adminkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box_req"
	adminrefertimeservice "git.gocasts.ir/ebhomengo/niki/service/admin/refer_time"
	agentkindboxservice "git.gocasts.ir/ebhomengo/niki/service/agent/kind_box"
	"git.gocasts.ir/ebhomengo/niki/service/auth"
	benefactoraddressservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/address"
	benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor"
	benefactorkindboxservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/kind_box"
	benefactorkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/kind_box_req"
	benefactorrefertimeservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/refer_time"
	"git.gocasts.ir/ebhomengo/niki/service/notification"
	adminvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/admin"
	adminkindboxvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box"
	adminkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box_req"
	agentkindboxvalidator "git.gocasts.ir/ebhomengo/niki/validator/agent/kind_box"
	benefactoraddressvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/address"
	benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor"
	benefactorkindboxvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box"
	benefactorkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box_req"
)

type Service struct {
	AdminAuthSvc            auth.Service
	AdminKindBoxSvc         adminkindboxservice.Service
	AdminKindBoxReqSvc      adminkindboxreqservice.Service
	AdminAuthorizeSvc       adminauthorizationservice.Service
	AdminSvc                adminservice.Service
	AdminAgentSvc           adminagentservice.Service
	AgentKindBoxSvc         agentkindboxservice.Service
	BenefactorAuthSvc       auth.Service
	BenefactorKindBoxSvc    benefactorkindboxservice.Service
	BenefactorKindBoxReqSvc benefactorkindboxreqservice.Service
	BenefactorAddressSvc    benefactoraddressservice.Service
	BenefactorSvc           benefactorservice.Service
	NotificationSvc         notification.Service
}

func New(cfg config.Config, db *mysql.DB, rds *redis.Adapter, smsAdapter smscontract.SmsAdapter) *Service {
	var (
		kindBoxRepo    = mysqlkindbox.New(db)
		kindBoxReqRepo = mysqlkindboxreq.New(db)
		addressRepo    = mysqladdress.New(db)
		benefactorRepo = mysqlbenefactor.New(db)
		adminRepo      = mysqladmin.New(db)
		referTimeRepo  = mysqlrefertime.New(db)
		agentRepo      = mysqlagent.New(db)
	)
	redisOtp := redisotp.New(rds)
	var (
		AdminAuthSvc       = auth.New(cfg.AdminAuth)
		AdminAuthorizeSvc  = adminauthorizationservice.New(adminRepo)
		AdminReferTimeSvc  = adminrefertimeservice.New(referTimeRepo)
		AdminAddressSvc    = adminaddressservice.New(addressRepo)
		AdminBenefactorSvc = adminbenefactorservice.New(benefactorRepo, AdminAddressSvc)
		AdminAgentSvc      = adminagentservice.New(agentRepo)

		AdminVld           = adminvalidator.New(adminRepo)
		AdminSvc           = adminservice.New(adminRepo, AdminAuthSvc, AdminVld)
		AdminKindBoxVld    = adminkindboxvalidator.New(kindBoxRepo, AdminAgentSvc)
		AdminKindBoxSvc    = adminkindboxservice.New(kindBoxRepo, AdminKindBoxVld)
		AdminKindBoxReqVld = adminkindboxreqvalidator.New(kindBoxReqRepo, AdminSvc, AdminAgentSvc, AdminBenefactorSvc, AdminReferTimeSvc, AdminAddressSvc)
		AdminKindBoxReqSvc = adminkindboxreqservice.New(kindBoxReqRepo, AdminKindBoxSvc, AdminKindBoxReqVld)
	)
	var (
		AgentKindBoxVld = agentkindboxvalidator.New(kindBoxRepo)
		AgentKindBoxSvc = agentkindboxservice.New(kindBoxRepo, AgentKindBoxVld)
	)
	var (
		BenefactorAuthSvc      = auth.New(cfg.BenefactorAuth)
		BenefactorReferTimeSvc = benefactorrefertimeservice.New(referTimeRepo)

		BenefactorVld           = benefactorvalidator.New()
		BenefactorSvc           = benefactorservice.New(cfg.BenefactorSvc, redisOtp, smsAdapter, BenefactorAuthSvc, benefactorRepo, BenefactorVld)
		BenefactorAddressVld    = benefactoraddressvalidator.New(BenefactorSvc, addressRepo)
		BenefactorAddressSvc    = benefactoraddressservice.New(addressRepo, BenefactorAddressVld)
		BenefactorKindBoxReqVld = benefactorkindboxreqvalidator.New(BenefactorSvc, BenefactorAddressSvc, BenefactorReferTimeSvc, kindBoxReqRepo)
		BenefactorKindBoxReqSvc = benefactorkindboxreqservice.New(kindBoxReqRepo, BenefactorKindBoxReqVld)
		BenefactorKindBoxVld    = benefactorkindboxvalidator.New(kindBoxRepo, BenefactorSvc, BenefactorAddressSvc, BenefactorReferTimeSvc)
		BenefactorKindBoxSvc    = benefactorkindboxservice.New(kindBoxRepo, BenefactorKindBoxVld)
	)
	NotificationSvc := notification.New(cfg.NotificationSvc, smsAdapter, AdminKindBoxReqSvc, AdminBenefactorSvc, AdminSvc, AdminKindBoxSvc)

	return &Service{
		AdminAuthSvc:            AdminAuthSvc,
		AdminKindBoxSvc:         AdminKindBoxSvc,
		AdminKindBoxReqSvc:      AdminKindBoxReqSvc,
		AdminAuthorizeSvc:       AdminAuthorizeSvc,
		AdminSvc:                AdminSvc,
		AdminAgentSvc:           AdminAgentSvc,
		AgentKindBoxSvc:         AgentKindBoxSvc,
		BenefactorAuthSvc:       BenefactorAuthSvc,
		BenefactorKindBoxSvc:    BenefactorKindBoxSvc,
		BenefactorKindBoxReqSvc: BenefactorKindBoxReqSvc,
		BenefactorAddressSvc:    BenefactorAddressSvc,
		BenefactorSvc:           BenefactorSvc,
		NotificationSvc:         NotificationSvc,
	}
}