package handlers import ( "errors" "net/http" "strconv" "strings" "time" "game-admin/internal/config" "game-admin/internal/models" "github.com/gin-gonic/gin" "github.com/uptrace/bun" ) type LanguageHandler struct { db *bun.DB cfg *config.Config } func NewLanguageHandler(db *bun.DB, cfg *config.Config) *LanguageHandler { return &LanguageHandler{db: db, cfg: cfg} } func (h *LanguageHandler) List(c *gin.Context) { var languages []models.Language err := h.db.NewSelect(). Model(&languages). OrderExpr("id ASC"). Scan(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, languages) } func (h *LanguageHandler) GetByID(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid language id"}) return } language := new(models.Language) err = h.db.NewSelect(). Model(language). Where("id = ?", id). Scan(c) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Language not found"}) return } c.JSON(http.StatusOK, language) } func (h *LanguageHandler) Create(c *gin.Context) { var req models.UpsertLanguageRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } code, name, err := normalizeLanguageRequest(req) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } language := &models.Language{ Code: code, Name: name, CreatedAt: time.Now(), UpdatedAt: time.Now(), } _, err = h.db.NewInsert().Model(language).Exec(c) if err != nil { c.JSON(http.StatusConflict, gin.H{"error": "Language code already exists"}) return } c.JSON(http.StatusCreated, language) } func (h *LanguageHandler) Update(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid language id"}) return } var req models.UpsertLanguageRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } code, name, err := normalizeLanguageRequest(req) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } res, err := h.db.NewUpdate(). Model((*models.Language)(nil)). Set("code = ?", code). Set("name = ?", name). Set("updated_at = ?", time.Now()). Where("id = ?", id). Exec(c) if err != nil { c.JSON(http.StatusConflict, gin.H{"error": "Could not update language"}) return } if affected, _ := res.RowsAffected(); affected == 0 { c.JSON(http.StatusNotFound, gin.H{"error": "Language not found"}) return } updated := new(models.Language) err = h.db.NewSelect(). Model(updated). Where("id = ?", id). Scan(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, updated) } func (h *LanguageHandler) Delete(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid language id"}) return } res, err := h.db.NewDelete(). Model((*models.Language)(nil)). Where("id = ?", id). Exec(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } if affected, _ := res.RowsAffected(); affected == 0 { c.JSON(http.StatusNotFound, gin.H{"error": "Language not found"}) return } c.JSON(http.StatusOK, gin.H{"message": "Language deleted"}) } func normalizeLanguageRequest(req models.UpsertLanguageRequest) (string, string, error) { code := strings.ToLower(strings.TrimSpace(req.Code)) name := strings.TrimSpace(req.Name) if code == "" { return "", "", errors.New("code is required") } if name == "" { return "", "", errors.New("name is required") } return code, name, nil }