package User

import (
	dto "astrology-api/dto/consultation"
	"astrology-api/middleware"
	services "astrology-api/services"
	"astrology-api/utils"
	"errors"
	"strconv"

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

// The customer's side of the waiting queue: join an astrologer's queue when
// they are busy, poll for the turn, connect when notified, or leave.

// JoinQueue — POST /api/user/consultation/queue/join
func (c *ConsultationController) JoinQueue(ctx *gin.Context) {

	userID := middleware.GetUserID(ctx)

	if userID == 0 {
		utils.Unauthorized(ctx, "Unauthorized")
		return
	}

	var request dto.JoinQueueRequest

	if err := ctx.ShouldBindJSON(&request); err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	response, err := c.consultationService.JoinQueue(userID, request)

	if err != nil {
		queueError(ctx, err)
		return
	}

	utils.Success(ctx, response.Message, response)
}

// GetQueueStatus — GET /api/user/consultation/queue/status[?queue_id=]
func (c *ConsultationController) GetQueueStatus(ctx *gin.Context) {

	userID := middleware.GetUserID(ctx)

	if userID == 0 {
		utils.Unauthorized(ctx, "Unauthorized")
		return
	}

	queueID, _ := strconv.ParseUint(ctx.Query("queue_id"), 10, 64)

	response, err := c.consultationService.GetQueueStatus(userID, uint(queueID))

	if err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	utils.Success(ctx, "Waiting queue status", response)
}

// ConnectQueue — POST /api/user/consultation/queue/connect
func (c *ConsultationController) ConnectQueue(ctx *gin.Context) {

	userID := middleware.GetUserID(ctx)

	if userID == 0 {
		utils.Unauthorized(ctx, "Unauthorized")
		return
	}

	var request dto.QueueActionRequest

	if err := ctx.ShouldBindJSON(&request); err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	response, err := c.consultationService.ConnectQueue(userID, request.QueueID)

	if err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	utils.Success(ctx, response.Message, response)
}

// CancelQueue — POST /api/user/consultation/queue/cancel
func (c *ConsultationController) CancelQueue(ctx *gin.Context) {

	userID := middleware.GetUserID(ctx)

	if userID == 0 {
		utils.Unauthorized(ctx, "Unauthorized")
		return
	}

	var request dto.QueueActionRequest

	if err := ctx.ShouldBindJSON(&request); err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	response, err := c.consultationService.CancelQueue(userID, request.QueueID)

	if err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	utils.Success(ctx, response.Message, response)
}

// queueError answers an already-queued customer with 409, anything else 400.
func queueError(ctx *gin.Context, err error) {

	var duplicate *services.QueueDuplicateError

	if errors.As(err, &duplicate) {
		utils.Conflict(ctx, duplicate.Message)
		return
	}

	utils.BadRequest(ctx, err.Error())
}
