package controller import ( "net/http" "strconv" "users_management/m/config" "users_management/m/middleware" "users_management/m/model/dto/req" "users_management/m/usecase" "users_management/m/utils/common" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type NearestDeviceController struct { nearestDeviceUC usecase.NearestDeviceUseCase rg *gin.RouterGroup cfg *config.Config } func NewNearestDeviceController(nearestDeviceUC usecase.NearestDeviceUseCase, rg *gin.RouterGroup, cfg *config.Config) *NearestDeviceController { return &NearestDeviceController{ nearestDeviceUC: nearestDeviceUC, rg: rg, cfg: cfg, } } func (c *NearestDeviceController) Route() { nearestDevices := c.rg.Group("/nearest-devices") nearestDevices.Use(middleware.ConditionalRequireAnyRole(c.cfg,"Teknisi", "Admin", "Super Admin")) { nearestDevices.POST("/search", c.getNearestDevices) nearestDevices.GET("/:id", c.getNearestDeviceByID) nearestDevices.POST("/towers/search", c.getNearestTowers) nearestDevices.GET("/towers/:id", c.getNearestTowerByID) } } func (c *NearestDeviceController) getNearestTowers(ctx *gin.Context) { var request req.NearestTowerDTO if err := ctx.ShouldBindJSON(&request); err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } towers, err := c.nearestDeviceUC.GetNearestTowers(request) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } response := gin.H{ "towers": towers, "total": len(towers), "search_params": gin.H{ "latitude": request.Latitude, "longitude": request.Longitude, "radius": request.Radius, "province": request.Province, "city": request.City, "district": request.District, }, } common.SingleResponses(ctx, "Nearest towers retrieved successfully", response) } func (c *NearestDeviceController) getNearestTowerByID(ctx *gin.Context) { id := ctx.Param("id") towerID, err := uuid.Parse(id) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid tower ID") return } // Get user coordinates from query params latStr := ctx.Query("lat") lngStr := ctx.Query("lng") if latStr == "" || lngStr == "" { common.ErrorResponses(ctx, http.StatusBadRequest, "User coordinates (lat, lng) are required") return } userLat, err := strconv.ParseFloat(latStr, 64) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid latitude") return } userLng, err := strconv.ParseFloat(lngStr, 64) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid longitude") return } tower, err := c.nearestDeviceUC.GetNearestTowerByID(towerID, userLat, userLng) if err != nil { common.ErrorResponses(ctx, http.StatusNotFound, err.Error()) return } common.SingleResponses(ctx, "Tower details retrieved successfully", tower) } func (c *NearestDeviceController) getNearestDevices(ctx *gin.Context) { var request req.NearestDeviceDTO if err := ctx.ShouldBindJSON(&request); err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } devices, err := c.nearestDeviceUC.GetNearestDevices(request) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } response := gin.H{ "devices": devices, "total": len(devices), "search_params": gin.H{ "latitude": request.Latitude, "longitude": request.Longitude, "radius": request.Radius, "province": request.Province, "city": request.City, "district": request.District, }, } common.SingleResponses(ctx, "Nearest devices retrieved successfully", response) } func (c *NearestDeviceController) getNearestDeviceByID(ctx *gin.Context) { id := ctx.Param("id") deviceID, err := uuid.Parse(id) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid device ID") return } // Get user coordinates from query params latStr := ctx.Query("lat") lngStr := ctx.Query("lng") if latStr == "" || lngStr == "" { common.ErrorResponses(ctx, http.StatusBadRequest, "User coordinates (lat, lng) are required") return } userLat, err := strconv.ParseFloat(latStr, 64) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid latitude") return } userLng, err := strconv.ParseFloat(lngStr, 64) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid longitude") return } device, err := c.nearestDeviceUC.GetNearestDeviceByID(deviceID, userLat, userLng) if err != nil { common.ErrorResponses(ctx, http.StatusNotFound, err.Error()) return } common.SingleResponses(ctx, "Device details retrieved successfully", device) }