package api

import (
	"fmt"
	"net/http"
	"products/app/cfg"
	"products/app/db"
	"strconv"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

func handlePing(c *gin.Context) {
	c.JSON(
		http.StatusOK,
		PingDto{
			Message: "Pong!",
		},
	)
}

func handleGetProducts(dbConn *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		var (
			machineId *int = nil
			err       error
			mId       int
		)

		machineIdStr, ok := c.GetQuery("machineId")
		if ok && len(machineIdStr) > 0 {
			if mId, err = strconv.Atoi(machineIdStr); err != nil {
				raiseBadRequestError(c, "Invalid machineId filter")
				return
			}
			machineId = &mId
		}

		products := db.GetProducts(dbConn, machineId)

		// for i := 0; i < len(*products); i++ {
		// 	(*products)[i].Name = fmt.Sprintf("[local] %s", (*products)[i].Name)
		// }

		c.JSON(
			http.StatusOK,
			GetProductsResponse{
				Products: *products,
			},
		)
	}
}

func handleGetProduct(dbConn *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		productId, err := strconv.Atoi(c.Param("productId"))
		if err != nil {
			raiseBadRequestError(c, "Invalid productId parameter")
			return
		}

		product, err := db.GetProduct(dbConn, productId)
		if err != nil {
			raiseNotFoundError(c, "Product not found")
			return
		}

		c.JSON(
			http.StatusOK,
			product,
		)
	}
}

func initRouter(dbConn *gorm.DB) *gin.Engine {
	gin.SetMode(gin.ReleaseMode)
	router := gin.Default()
	router.Use(corsMiddleware())

	routes := router.Group("/products")
	{
		routes.GET("/ping", handlePing)
		routes.GET("", handleGetProducts(dbConn))
		routes.GET("/:productId", handleGetProduct(dbConn))
	}

	return router
}

func Serve(dbConn *gorm.DB) {
	serverAddr := fmt.Sprintf("%s:%d", cfg.Config.AppHost, cfg.Config.AppPort)
	fmt.Printf("Starting serving on %s\n", serverAddr)

	router := initRouter(dbConn)
	router.Run(serverAddr)
}
