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"
	adminaddressaggservice "git.gocasts.ir/ebhomengo/niki/service/admin/address_aggregator"
	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"
	adminbenefactoraggsvc "git.gocasts.ir/ebhomengo/niki/service/admin/benefactor_aggregator"
	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"
	adminrefertimeaggservice "git.gocasts.ir/ebhomengo/niki/service/admin/refer_time_aggregator"
	agentkindboxservice "git.gocasts.ir/ebhomengo/niki/service/agent/kind_box"
	agentkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/agent/kind_box_req"
	"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"
	adminseederservice "git.gocasts.ir/ebhomengo/niki/service/seeder"
	adminvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/admin"
	adminbenefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/benefactor"
	adminkindboxvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box"
	adminkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box_req"
	adminrefertimevalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/refer_time"
	agentkindboxvalidator "git.gocasts.ir/ebhomengo/niki/validator/agent/kind_box"
	agentkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/agent/kind_box_req"
	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
	AdminAddressSvc         adminaddressservice.Service
	AdminAuthorizeSvc       adminauthorizationservice.Service
	AdminSvc                adminservice.Service
	AdminAgentSvc           adminagentservice.Service
	AdminBenefactorSvc      adminbenefactorservice.Service
	AgentKindBoxSvc         agentkindboxservice.Service
	AgentKindBoxReqSvc      agentkindboxreqservice.Service
	BenefactorAuthSvc       auth.Service
	BenefactorKindBoxSvc    benefactorkindboxservice.Service
	BenefactorKindBoxReqSvc benefactorkindboxreqservice.Service
	BenefactorAddressSvc    benefactoraddressservice.Service
	BenefactorSvc           benefactorservice.Service
	NotificationSvc         notification.Service
	BenefactorReferTimeSvc  benefactorrefertimeservice.Service
	AdminReferTimeSvc       adminrefertimeservice.Service
	AdminBenefactorAggSvc   adminbenefactoraggsvc.Service
	AdminAddressAggSvc      adminaddressaggservice.Service
	AdminReferTimeAggSvc    adminrefertimeaggservice.Service
	AdminSeedSvc            adminseederservice.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)
		AdminReferTimeVld  = adminrefertimevalidator.New()
		AdminReferTimeSvc  = adminrefertimeservice.New(referTimeRepo, AdminReferTimeVld)
		AdminAddressSvc    = adminaddressservice.New(addressRepo)
		AdminBenefactorVld = adminbenefactorvalidator.New(benefactorRepo)
		AdminBenefactorSvc = adminbenefactorservice.New(benefactorRepo, AdminAddressSvc, AdminBenefactorVld)
		AdminAgentSvc      = adminagentservice.New(agentRepo)

		AdminSeedSvc = adminseederservice.New(benefactorRepo, kindBoxRepo, kindBoxReqRepo, addressRepo)

		AdminBenefactorAggSvc = adminbenefactoraggsvc.New(benefactorRepo)
		AdminAddressAggSvc    = adminaddressaggservice.New(addressRepo)
		AdminReferTimeAggSvc  = adminrefertimeaggservice.New(referTimeRepo)

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

		BenefactorVld           = benefactorvalidator.New(benefactorRepo)
		BenefactorSvc           = benefactorservice.New(cfg.BenefactorSvc, redisOtp, smsAdapter, BenefactorAuthSvc, benefactorRepo, BenefactorVld)
		BenefactorAddressVld    = benefactoraddressvalidator.New(addressRepo)
		BenefactorAddressSvc    = benefactoraddressservice.New(addressRepo, BenefactorAddressVld)
		BenefactorKindBoxReqVld = benefactorkindboxreqvalidator.New(BenefactorAddressSvc, BenefactorReferTimeSvc, kindBoxReqRepo)
		BenefactorKindBoxReqSvc = benefactorkindboxreqservice.New(kindBoxReqRepo, BenefactorKindBoxReqVld)
		BenefactorKindBoxVld    = benefactorkindboxvalidator.New(kindBoxRepo, 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,
		AdminAddressSvc:         AdminAddressSvc,
		AdminAuthorizeSvc:       AdminAuthorizeSvc,
		AdminSvc:                AdminSvc,
		AdminAgentSvc:           AdminAgentSvc,
		AdminBenefactorSvc:      AdminBenefactorSvc,
		AgentKindBoxSvc:         AgentKindBoxSvc,
		AgentKindBoxReqSvc:      AgentKindBoxReqSvc,
		BenefactorAuthSvc:       BenefactorAuthSvc,
		BenefactorKindBoxSvc:    BenefactorKindBoxSvc,
		BenefactorKindBoxReqSvc: BenefactorKindBoxReqSvc,
		BenefactorAddressSvc:    BenefactorAddressSvc,
		BenefactorSvc:           BenefactorSvc,
		NotificationSvc:         NotificationSvc,
		BenefactorReferTimeSvc:  BenefactorReferTimeSvc,
		AdminReferTimeSvc:       AdminReferTimeSvc,
		AdminBenefactorAggSvc:   AdminBenefactorAggSvc,
		AdminAddressAggSvc:      AdminAddressAggSvc,
		AdminReferTimeAggSvc:    AdminReferTimeAggSvc,
		AdminSeedSvc:            AdminSeedSvc,
	}
}
