package httpserver

import (
	"fmt"

	config "git.gocasts.ir/ebhomengo/niki/config"
	adminhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/admin"
	adminkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/kind_box_req"
	benefactoraddresshandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/address"
	benefactorhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/benefactor"
	benefactorkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/kind_box_req"
	adminservice "git.gocasts.ir/ebhomengo/niki/service/admin/admin"
	adminkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box_req"
	authservice "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"
	benefactorkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/kind_box_req"
	adminvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/admin"
	adminkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box_req"
	benefactoraddressvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/address"
	benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor"
	benefactorkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box_req"
	echo "github.com/labstack/echo/v4"
	middleware "github.com/labstack/echo/v4/middleware"
)

type Server struct {
	config                      config.Config
	Router                      *echo.Echo
	benefactorHandler           benefactorhandler.Handler
	benefactorKindBoxReqHandler benefactorkindboxreqhandler.Handler
	benefactorAddressHandler    benefactoraddresshandler.Handler
	adminHandler                adminhandler.Handler
	adminKindBoxReqHandler      adminkindboxreqhandler.Handler
}

func New(
	cfg config.Config,
	benefactorSvc benefactorservice.Service,
	benefactorVld benefactorvalidator.Validator,
	benefactorAuthSvc authservice.Service,
	benefactorKindBoxReqSvc benefactorkindboxreqservice.Service,
	benefactorKindBoxReqVld benefactorkindboxreqvalidator.Validator,
	benefactorAddressSvc benefactoraddressservice.Service,
	benefactorAddressVld benefactoraddressvalidator.Validator,
	adminSvc adminservice.Service,
	adminVld adminvalidator.Validator,
	adminAuthSvc authservice.Service,
	adminKinBoxReqSvc adminkindboxreqservice.Service,
	adminKinBoxReqVld adminkindboxreqvalidator.Validator,
) Server {
	return Server{
		Router:                      echo.New(),
		config:                      cfg,
		benefactorHandler:           benefactorhandler.New(cfg.Auth, benefactorAuthSvc, benefactorSvc, benefactorVld),
		benefactorKindBoxReqHandler: benefactorkindboxreqhandler.New(cfg.Auth, benefactorAuthSvc, benefactorKindBoxReqSvc, benefactorKindBoxReqVld),
		benefactorAddressHandler:    benefactoraddresshandler.New(cfg.Auth, benefactorAuthSvc, benefactorAddressSvc, benefactorAddressVld),
		adminHandler:                adminhandler.New(cfg.AdminAuth, adminAuthSvc, adminSvc, adminVld),
		adminKindBoxReqHandler:      adminkindboxreqhandler.New(cfg.Auth, adminAuthSvc, adminKinBoxReqSvc, adminKinBoxReqVld),
	}
}

func (s Server) Serve() {
	s.Router.Use(middleware.RequestID())

	s.Router.Use(middleware.Recover())

	// Routes
	s.Router.GET("/health-check", s.healthCheck)
	s.benefactorHandler.SetRoutes(s.Router)
	s.benefactorKindBoxReqHandler.SetRoutes(s.Router)
	s.benefactorAddressHandler.SetRoutes(s.Router)
	s.adminHandler.SetRoutes(s.Router)
	s.adminKindBoxReqHandler.SetRoutes(s.Router)

	// Start server
	address := fmt.Sprintf(":%d", s.config.HTTPServer.Port)
	fmt.Printf("start echo server on %s\n", address)
	if err := s.Router.Start(address); err != nil {
		fmt.Println("router start error", err)
	}
}
