package web

import (
	"errors"
	"net/http"

	"party.at/party/cmd/party/common"
	"party.at/party/internal/data"
)

func (web *Web) VoteAction(w http.ResponseWriter, r *http.Request) {
	var input struct {
		IssueID   int64  `json:"issue_id"`
		OptionID  int64  `json:"option_id"`
		Nonce     []byte `json:"nonce"`
		Signature []byte `json:"signature"`
	}

	if err := common.ReadJSON(w, r, &input); err != nil {
		common.WriteJSON(w, http.StatusBadRequest, common.Envelope{"error": map[string]string{"message": err.Error()}}, nil)
		return
	}

	if err := web.App.CastVote(input.IssueID, input.OptionID, input.Nonce, input.Signature); err != nil {
		switch {
		case errors.Is(err, data.ErrRecordNotFound):
			common.WriteJSON(w, http.StatusNotFound, common.Envelope{"error": map[string]string{"message": "issue not found"}}, nil)
		case errors.Is(err, data.ErrInvalidSignature):
			common.WriteJSON(w, http.StatusUnprocessableEntity, common.Envelope{"error": map[string]string{"message": err.Error()}}, nil)
		case errors.Is(err, data.ErrDuplicateVote):
			common.WriteJSON(w, http.StatusConflict, common.Envelope{"error": map[string]string{"message": err.Error()}}, nil)
		default:
			web.App.LogError(r, err)
			common.WriteJSON(w, http.StatusInternalServerError, common.Envelope{"error": map[string]string{"message": "internal server error"}}, nil)
		}
		return
	}

	if err := common.WriteJSON(w, http.StatusOK, common.Envelope{"message": "vote successfully cast"}, nil); err != nil {
		web.App.LogError(r, err)
	}
}
