func (ctl *userController) Update(c *gin.Context) {
	id, exists := c.Get("user_id")
	if exists == false {
		HTTPRes(c, http.StatusBadRequest, "Invalid User ID", nil)
		return
	}
	user, err := ctl.us.GetByID(id.(uint))
	if err != nil {
		HTTPRes(c, http.StatusInternalServerError, err.Error(), nil)
		return
	}
	var userInput UserUpdateInput
	if err := c.ShouldBindJSON(&userInput); err != nil {
		HTTPRes(c, http.StatusBadRequest, err.Error(), nil)
		return
	}
	if user.ID != id {
		HTTPRes(c, http.StatusUnauthorized, "Unauthorized", nil)
		return
	}
	user.FirstName = userInput.FirstName
	user.LastName = userInput.LastName
	user.Email = userInput.Email
	if err := ctl.us.Update(user); err != nil {
		HTTPRes(c, http.StatusInternalServerError, err.Error(), nil)
		return
	}
	userOutput := ctl.mapToUserOutput(user)
	HTTPRes(c, http.StatusOK, "ok", userOutput)
}
@Summary Update account profile
@Produce  json
@Param email body string true "Email"
@Param firstName body string false "First Name"
@Param lastName body string false "Last Name"
@Success 200 {object} Response
@Failure 400 {object} Response
@Failure 500 {object} Response
@Router /api/account/profile [put]
package controllers
import (
	"errors"
	"net/http"
	"strconv"
	"strings"
	"github.com/yhagio/go_api_boilerplate/domain/user"
	"github.com/yhagio/go_api_boilerplate/services/authservice"
	"github.com/yhagio/go_api_boilerplate/services/emailservice"
	"github.com/yhagio/go_api_boilerplate/services/userservice"
	"github.com/gin-gonic/gin"
)
type UserInput struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}
type UserOutput struct {
	ID        uint   `json:"id"`
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
	Email     string `json:"email"`
	Role      string `json:"role"`
	Active    bool   `json:"active"`
}
type UserUpdateInput struct {
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
	Email     string `json:"email"`
}
type UserController interface {
	Register(*gin.Context)
	Login(*gin.Context)
	GetByID(*gin.Context)
	GetProfile(*gin.Context)
	Update(*gin.Context)
	ForgotPassword(*gin.Context)
	ResetPassword(*gin.Context)
}
type userController struct {
	us userservice.UserService
	as authservice.AuthService
	es emailservice.EmailService
}
func NewUserController(
	us userservice.UserService,
	as authservice.AuthService,
	es emailservice.EmailService) UserController {
	return &userController{
		us: us,
		as: as,
		es: es,
	}
}
func (ctl *userController) Register(c *gin.Context) {
	var userInput UserInput
	if err := c.ShouldBindJSON(&userInput); err != nil {
		HTTPRes(c, http.StatusBadRequest, err.Error(), nil)
		return
	}
	u := ctl.inputToUser(userInput)
	if err := ctl.us.Create(&u); err != nil {
		HTTPRes(c, http.StatusInternalServerError, err.Error(), nil)
		return
	}
	if err := ctl.es.Welcome(u.Email); err != nil {
		HTTPRes(c, http.StatusInternalServerError, err.Error(), nil)
		return
	}
	err := ctl.login(c, &u)
	if err != nil {
		HTTPRes(c, http.StatusInternalServerError, err.Error(), nil)
		return
	}
}
func (ctl *userController) Login(c *gin.Context) {
	var userInput UserInput
	if err := c.ShouldBindJSON(&userInput); err != nil {
		HTTPRes(c, http.StatusBadRequest, err.Error(), nil)
		return
	}
	user, err := ctl.us.GetByEmail(userInput.Email)
	if err != nil {
		HTTPRes(c, http.StatusInternalServerError, err.Error(), nil)
		return
	}
	err = ctl.us.ComparePassword(userInput.Password, user.Password)
	if err != nil {
		HTTPRes(c, http.StatusBadRequest, err.Error(), nil)
		return
	}
	err = ctl.login(c, user)
	if err != nil {
		HTTPRes(c, http.StatusInternalServerError, err.Error(), nil)
		return
	}
}
func (ctl *userController) GetByID(c *gin.Context) {
	id, err := ctl.getUserID(c.Param(("id")))
	if err != nil {
		HTTPRes(c, http.StatusBadRequest, err.Error(), nil)
		return
	}
	user, err := ctl.us.GetByID(id)
	if err != nil {
		es := err.Error()
		if strings.Contains(es, "not found") {
			HTTPRes(c, http.StatusNotFound, es, nil)
			return
		}
		HTTPRes(c, http.StatusInternalServerError, es, nil)
		return
	}
	userOutput := ctl.mapToUserOutput(user)
	HTTPRes(c, http.StatusOK, "ok", userOutput)
}
func (ctl *userController) GetProfile(c *gin.Context) {
	id, exists := c.Get("user_id")
	if exists == false {
		HTTPRes(c, http.StatusBadRequest, "Invalid User ID", nil)
		return
	}
	user, err := ctl.us.GetByID(id.(uint))
	if err != nil {
		HTTPRes(c, http.StatusInternalServerError, err.Error(), nil)
		return
	}
	userOutput := ctl.mapToUserOutput(user)
	HTTPRes(c, http.StatusOK, "ok", userOutput)
}