package api

import (
	"fmt"
	"net/http"

	"code.nonshy.com/nonshy/website/pkg/models"
	"code.nonshy.com/nonshy/website/pkg/session"
)

// ReadNotification API to mark a notif ID as "read."
func ReadNotification() http.HandlerFunc {
	// Request JSON schema.
	type Request struct {
		ID uint64 `json:"id"`
	}

	// Response JSON schema.
	type Response struct {
		OK    bool   `json:"OK"`
		Error string `json:"error,omitempty"`
	}

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			SendJSON(w, http.StatusNotAcceptable, Response{
				Error: "POST method only",
			})
			return
		}

		// Get the current user.
		currentUser, err := session.CurrentUser(r)
		if err != nil {
			SendJSON(w, http.StatusBadRequest, Response{
				Error: "Couldn't get current user!",
			})
			return
		}

		// Parse request payload.
		var req Request
		if err := ParseJSON(r, &req); err != nil {
			SendJSON(w, http.StatusBadRequest, Response{
				Error: fmt.Sprintf("Error with request payload: %s", err),
			})
			return
		}

		// Get this notification.
		notif, err := models.GetNotification(req.ID)
		if err != nil {
			SendJSON(w, http.StatusInternalServerError, Response{
				Error: err.Error(),
			})
			return
		}

		// Ensure it's ours to read.
		if notif.UserID != currentUser.ID {
			SendJSON(w, http.StatusForbidden, Response{
				Error: "That is not your notification.",
			})
			return
		}

		// Mark it read.
		notif.Read = true
		notif.Save()

		// Send success response.
		SendJSON(w, http.StatusOK, Response{
			OK: true,
		})
	})
}

// ClearNotification API to delete a single notification for the user.
func ClearNotification() http.HandlerFunc {
	// Request JSON schema.
	type Request struct {
		ID uint64 `json:"id"`
	}

	// Response JSON schema.
	type Response struct {
		OK    bool   `json:"OK"`
		Error string `json:"error,omitempty"`
	}

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			SendJSON(w, http.StatusNotAcceptable, Response{
				Error: "POST method only",
			})
			return
		}

		// Get the current user.
		currentUser, err := session.CurrentUser(r)
		if err != nil {
			SendJSON(w, http.StatusBadRequest, Response{
				Error: "Couldn't get current user!",
			})
			return
		}

		// Parse request payload.
		var req Request
		if err := ParseJSON(r, &req); err != nil {
			SendJSON(w, http.StatusBadRequest, Response{
				Error: fmt.Sprintf("Error with request payload: %s", err),
			})
			return
		}

		// Get this notification.
		notif, err := models.GetNotification(req.ID)
		if err != nil {
			SendJSON(w, http.StatusInternalServerError, Response{
				Error: err.Error(),
			})
			return
		}

		// Ensure it's ours to read.
		if notif.UserID != currentUser.ID {
			SendJSON(w, http.StatusForbidden, Response{
				Error: "That is not your notification.",
			})
			return
		}

		// Delete it.
		notif.Delete()

		// Send success response.
		SendJSON(w, http.StatusOK, Response{
			OK: true,
		})
	})
}
