package boot

import (
	"log"
	"net/http"

	"refund/internal/config"
	"refund/pkg/httpclient"

	"github.com/jmoiron/sqlx"

	userData "refund/internal/data/user"
	server "refund/internal/delivery/http"
	userHandler "refund/internal/delivery/http/user"
	userService "refund/internal/service/user"
)

// HTTP will load configuration, do dependency injection and then start the HTTP server
func HTTP() error {
	var (
		s     server.Server        // HTTP Server Object
		ud    userData.Data        // User domain data layer
		us    userService.Service  // User domain service layer
		uh    *userHandler.Handler // User domain handler
		cfg   *config.Config       // Configuration object
		httpc *httpclient.Client   // HTTP Client
	)

	// Get configuration
	err := config.Init()
	if err != nil {
		log.Fatalf("[CONFIG] Failed to initialize config: %v", err)
	}
	cfg = config.Get()

	httpc = httpclient.NewClient()

	// Open MySQL DB Connection
	db, err := sqlx.Open("mysql", cfg.Database.Master)
	if err != nil {
		log.Fatalf("[DB] Failed to initialize database connection: %v", err)
	}

	// User domain initialization
	ud = userData.New(db, httpc)
	us = userService.New(ud)
	uh = userHandler.New(us)

	// Inject service used on handler
	s = server.Server{
		User: uh,
	}

	// Error Handling
	if err := s.Serve(cfg.Server.Port); err != http.ErrServerClosed {
		return err
	}

	return nil
}
