package friend

import (
	"fmt"
	"net/http"
	"strings"

	"code.nonshy.com/nonshy/website/pkg/config"
	"code.nonshy.com/nonshy/website/pkg/log"
	"code.nonshy.com/nonshy/website/pkg/models"
	"code.nonshy.com/nonshy/website/pkg/session"
	"code.nonshy.com/nonshy/website/pkg/templates"
)

// AddFriend controller to send a friend request.
func AddFriend() http.HandlerFunc {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// POST only.
		if r.Method != http.MethodPost {
			session.FlashError(w, r, "Unacceptable Request Method")
			templates.Redirect(w, "/")
			return
		}

		// Form fields
		var (
			username = strings.ToLower(r.PostFormValue("username"))
			verdict  = r.PostFormValue("verdict")
		)

		// Get the current user.
		currentUser, err := session.CurrentUser(r)
		if err != nil {
			session.FlashError(w, r, "Couldn't get CurrentUser: %s", err)
			templates.Redirect(w, "/")
			return
		}

		// Get the target user.
		user, err := models.FindUser(username)
		if err != nil {
			session.FlashError(w, r, "User Not Found")
			templates.Redirect(w, "/")
			return
		}

		// Can't friend yourself.
		if currentUser.ID == user.ID {
			session.FlashError(w, r, "You can't send a friend request to yourself!")
			templates.Redirect(w, "/u/"+username)
			return
		}

		// Are we adding, or rejecting+removing?
		if verdict == "reject" || verdict == "remove" {
			err := models.RemoveFriend(currentUser.ID, user.ID)
			if err != nil {
				session.FlashError(w, r, "Failed to remove friend: %s", err)
				templates.Redirect(w, "/u/"+username)
				return
			}

			var message string
			if verdict == "reject" {
				message = fmt.Sprintf("Friend request from %s has been rejected.", username)
			} else {
				message = fmt.Sprintf("Removed friendship with %s.", username)
			}

			session.Flash(w, r, message)
			if verdict == "reject" {
				templates.Redirect(w, "/friends?view=requests")
			}
			templates.Redirect(w, "/friends")
			return
		} else if verdict == "ignore" {
			if err := models.IgnoreFriendRequest(currentUser, user); err != nil {
				session.FlashError(w, r, "Error marking the friend request as ignored: %s", err)
			} else {
				session.Flash(w, r, "You have ignored the friend request from %s.", username)
			}
			templates.Redirect(w, "/friends")
			return
		} else {
			// Post the friend request.
			if err := models.AddFriend(currentUser.ID, user.ID); err != nil {
				session.FlashError(w, r, "Couldn't send friend request: %s.", err)
			} else {
				if verdict == "approve" {
					// Notify the requestor they'd been approved.
					if !user.NotificationOptOut(config.NotificationOptOutFriendRequestAccepted) {
						notif := &models.Notification{
							UserID:    user.ID,
							AboutUser: *currentUser,
							Type:      models.NotificationFriendApproved,
						}
						if err := models.CreateNotification(notif); err != nil {
							log.Error("Couldn't create approved notification: %s", err)
						}
					}

					session.Flash(w, r, "You accepted the friend request from %s!", username)
					templates.Redirect(w, "/friends?view=requests")
					return
				}
				session.Flash(w, r, "Friend request sent!")
			}
		}

		templates.Redirect(w, "/u/"+username)
	})
}
