package account

import (
	"fmt"
	"net/http"

	"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"
)

// InnerCircle is the landing page for inner circle members only.
func InnerCircle() http.HandlerFunc {
	tmpl := templates.Must("account/inner_circle.html")
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		currentUser, err := session.CurrentUser(r)
		if err != nil || !currentUser.IsInnerCircle() {
			templates.NotFoundPage(w, r)
			return
		}

		var vars = map[string]interface{}{
			"InnerCircleMinimumPublicPhotos": config.InnerCircleMinimumPublicPhotos,
		}

		if err := tmpl.Execute(w, r, vars); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	})
}

// InviteCircle is the landing page to invite a user into the circle.
func InviteCircle() http.HandlerFunc {
	tmpl := templates.Must("account/invite_circle.html")
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		currentUser, err := session.CurrentUser(r)
		if err != nil || !currentUser.IsInnerCircle() {
			templates.NotFoundPage(w, r)
			return
		}

		// Invite whom?
		username := r.FormValue("to")
		user, err := models.FindUser(username)
		if err != nil {
			templates.NotFoundPage(w, r)
			return
		}

		if currentUser.ID == user.ID && currentUser.InnerCircle {
			session.FlashError(w, r, "You are already part of the inner circle.")
			templates.Redirect(w, "/inner-circle")
			return
		}

		// Any blocking?
		if models.IsBlocking(currentUser.ID, user.ID) && !currentUser.IsAdmin {
			session.FlashError(w, r, "You are blocked from inviting this user to the circle.")
			templates.Redirect(w, "/inner-circle")
			return
		}

		// POSTing?
		if r.Method == http.MethodPost {
			var (
				confirm = r.FormValue("intent") == "confirm"
			)

			if !confirm {
				templates.Redirect(w, "/u/"+username)
				return
			}

			// Add them!
			if err := models.AddToInnerCircle(user); err != nil {
				session.FlashError(w, r, "Couldn't add to the inner circle: %s", err)
			}

			log.Info("InnerCircle: %s adds %s to the inner circle", currentUser.Username, user.Username)

			session.Flash(w, r, "%s has been added to the inner circle!", user.Username)
			templates.Redirect(w, "/photo/u/"+user.Username)
			return
		}

		var vars = map[string]interface{}{
			"User": user,
		}
		if err := tmpl.Execute(w, r, vars); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	})
}

// RemoveCircle is the admin-only page to remove a member from the circle.
func RemoveCircle() http.HandlerFunc {
	tmpl := templates.Must("account/remove_circle.html")
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		currentUser, err := session.CurrentUser(r)
		if err != nil || !currentUser.IsInnerCircle() {
			templates.NotFoundPage(w, r)
			return
		}

		// Remove whom?
		username := r.FormValue("to")
		user, err := models.FindUser(username)
		if err != nil {
			templates.NotFoundPage(w, r)
			return
		}

		// POSTing?
		if r.Method == http.MethodPost {
			var (
				confirm = r.FormValue("intent") == "confirm"
			)

			if !confirm {
				templates.Redirect(w, "/u/"+username)
				return
			}

			// Admin (with the correct scope): remove them now.
			if currentUser.HasAdminScope(config.ScopeCircleModerator) {
				if err := models.RemoveFromInnerCircle(user); err != nil {
					session.FlashError(w, r, "Couldn't remove from the inner circle: %s", err)
				}

				session.Flash(w, r, "%s has been removed from the inner circle!", user.Username)
			} else {
				// Non-admin user: request removal only.
				fb := &models.Feedback{
					Intent:    "report.circle",
					Subject:   "Inner Circle Removal Request",
					TableName: "users",
					TableID:   user.ID,
					Message: fmt.Sprintf(
						"An inner circle member has flagged that **%s** no longer qualifies to be a part of the inner circle and should be removed.",
						user.Username,
					),
				}

				if err := models.CreateFeedback(fb); err != nil {
					session.FlashError(w, r, "Couldn't create admin notification: %s", err)
				} else {
					session.Flash(w, r, "A request to remove %s from the inner circle has been sent to the site admin.", user.Username)
				}
			}

			templates.Redirect(w, "/u/"+user.Username)
			return
		}

		var vars = map[string]interface{}{
			"User": user,
		}
		if err := tmpl.Execute(w, r, vars); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	})
}
