package controllers

import (
	"net/http"

	"learnsteam/learsteam-quiz-api/internal/models"
	"learnsteam/learsteam-quiz-api/internal/services"

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

type AuthController interface {
	Register(*gin.Context)
	Login(*gin.Context)
}

type authController struct {
	service      services.AuthService
	tokenService services.TokenService
}

func NewAuthController(service services.AuthService, tokenService services.TokenService) AuthController {
	return &authController{
		service:      service,
		tokenService: tokenService,
	}
}

// Register
//
// @Summary			회원가입
// @Description	username, name, password 를 입력하여 회원가입
// @Tags				회원가입
// @Accept			json
// @Produce			json
//
// @Param username body string true "username"
// @Param name body string true "이름"
// @Param password body string true "비밀번호"
//
// @Success			200		{object} models.RegisterResponse
// @Router				/auth/register [post]
func (controller *authController) Register(c *gin.Context) {
	var params models.RegisterRequest
	if c.BindJSON(&params) != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "bad request"})
		return
	}

	user, err := controller.service.Register(&params)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	token, err := controller.tokenService.Create(user.ID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"user": user, "token": token.Token, "refresh_token": token.RefreshToken})
}

// Login 사용자 로그인
//
// @Summary 			사용자 로그인 로그인
// @Description		사용자가 로그인합니다.
// @Tags					로그인
// @Accept				json
// @Produce				json
//
// @Param username body string true "username"
// @Param password body string true "비밀번호"
//
// @Success			200		{object} models.LoginResponse
// @Router				/auth/login [post]
func (controller *authController) Login(c *gin.Context) {
	var request models.LoginRequest
	if err := c.BindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	user, err := controller.service.Login(&request)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	token, err := controller.tokenService.Create(user.ID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"user":          user,
		"token":         token.Token,
		"refresh_token": token.RefreshToken,
	})
}

// Logout
func (controller *authController) Logout(c *gin.Context) {
	token := c.GetHeader("Authorization")
	if token == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "bad request"})
		return
	}

	err := controller.tokenService.Delete(token)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.SetCookie("Authorization", "", -1, "/", "localhost", false, true)
	c.SetCookie("RefreshToken", "", -1, "/", "localhost", false, true)
	c.SetCookie("ExpiresAt", "", -1, "/", "localhost", false, true)
	c.SetCookie("RefreshExpiresAt", "", -1, "/", "localhost", false, true)
	c.SetCookie("RefreshTokenExpiresAt", "", -1, "/", "localhost", false, true)
	c.SetCookie("RefreshTokenExpiresAt", "", -1, "/", "localhost", false, true)
	c.SetCookie("RefreshTokenExpiresAt", "", -1, "/", "localhost", false, true)
	c.JSON(http.StatusOK, gin.H{"message": "logout"})
}
