package controller

import (
	_const "chonho/const"
	"chonho/internal/api-v1/entity"
	"chonho/internal/api-v1/usecase/authentication_usecase"
	_error "chonho/pkg/c_error"
	"github.com/gin-gonic/gin"
	"strings"
)

type AuthenticationController struct {
	Controller
	authUseCase authentication_usecase.UseCase
}

func NewAuthenticationController(authUseCase authentication_usecase.UseCase) *AuthenticationController {
	return &AuthenticationController{
		authUseCase: authUseCase,
	}
}

// RegisterByDevice godoc
// @Summary Anonymous register
// @Description Register temporary user by device id
// @Tags Authentication
// @ID user-anonymous
// @Accept json
// @Produce json
// @Param json body entity.RegisterByDeviceRequest true "Device and user data"
// @Success 200 {object} entity.UserResponse
// @Failure 400 {object} entity.Response
// @Router /register-by-device [post]
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (h *AuthenticationController) RegisterByDevice(ctx *gin.Context) {
	var request entity.RegisterByDeviceRequest
	if h.WrapBindAndValidate(ctx, &request) {
		data, err := h.authUseCase.RegisterUserByDevice(&request, ctx)
		h.WrapResponse(ctx, data, err)
	}
}

// Register godoc
// @Summary User register
// @Description Register new user
// @Tags Authentication
// @ID user-register
// @Accept json
// @Produce json
// @Param json body entity.RegisterRequest true "New user data"
// @Success 200 {object} entity.UserResponse
// @Failure 400 {object} entity.Response
// @Router /register [post]
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (h *AuthenticationController) Register(ctx *gin.Context) {
	var request entity.RegisterRequest
	if h.WrapBindAndValidate(ctx, &request) {
		data, err := h.authUseCase.RegisterUser(&request, ctx)
		h.WrapResponse(ctx, data, err)
	}
}

// Login godoc
// @Summary Login
// @Description Login with phone/password
// @Tags Authentication
// @ID user-login
// @Accept json
// @Produce json
// @Param json body entity.LoginRequest true "phone/password"
// @Success 200 {object} entity.UserResponse
// @Failure 400 {object} entity.Response
// @Router /login [post]
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
// @Security AppDeviceId
func (h *AuthenticationController) Login(ctx *gin.Context) {
	var request entity.LoginRequest
	if h.WrapBindAndValidate(ctx, &request) {
		deviceId := ctx.GetHeader(_const.HeaderDeviceIdKey)
		data, err := h.authUseCase.Login(&request, deviceId, ctx)
		h.WrapResponse(ctx, data, err)
	}
}

// LoginWithFireBaseToken godoc
// @Summary Login
// @Description Retrieve user info with firebase id token
// @Tags Authentication
// @ID user-login-token
// @Accept json
// @Produce json
// @Param json body entity.LoginByTokenRequest true "phone/password"
// @Success 200 {object} entity.UserResponse
// @Failure 400 {object} entity.Response
// @Router /login-by-token [post]
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (h *AuthenticationController) LoginWithFireBaseToken(ctx *gin.Context) {
	var request entity.LoginByTokenRequest
	if h.WrapBindAndValidate(ctx, &request) {
		data, err := h.authUseCase.LoginByToken(request.FirebaseIdToken, ctx)
		h.WrapResponse(ctx, data, err)
	}
}

// PhoneCheck godoc
// @Summary check phone has registered
// @Tags Authentication
// @ID user-phone-check
// @Accept json
// @Produce json
// @Param phone path string true "phone"
// @Success 200 {object} entity.Response
// @Failure 400 {object} entity.Response
// @Router /check/{phone} [get]
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (h *AuthenticationController) PhoneCheck(ctx *gin.Context) {
	phone, exist := ctx.GetQuery("phone")
	if !exist {
		phone = ctx.Param("phone")
	}
	if phone == "" {
		h.Failure(ctx, _error.New(_const.StatusBadRequest, "phone is invalid"))
	} else {
		phone = strings.ReplaceAll(phone, "+84", "0")
		err := h.authUseCase.CheckPhoneNumber(phone, ctx)
		h.WrapResponse(ctx, nil, err)
	}
}
