package photo

import (
	"net/http"

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

// SiteGallery controller (/photo/gallery) to view all members' public gallery pics.
func SiteGallery() http.HandlerFunc {
	tmpl := templates.Must("photo/gallery.html")

	// Whitelist for ordering options.
	var sortWhitelist = []string{
		"created_at desc",
		"created_at asc",
	}

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Query params.
		var (
			viewStyle = r.FormValue("view") // cards (default), full

			// Search filters.
			filterExplicit   = r.FormValue("explicit")
			filterVisibility = r.FormValue("visibility")
			adminView        = r.FormValue("admin_view") == "true"
			sort             = r.FormValue("sort")
			sortOK           bool
		)

		// Sort options.
		for _, v := range sortWhitelist {
			if sort == v {
				sortOK = true
				break
			}
		}
		if !sortOK {
			sort = "created_at desc"
		}

		// Defaults.
		if viewStyle != "full" {
			viewStyle = "cards"
		}

		// Load the current user.
		currentUser, err := session.CurrentUser(r)
		if err != nil {
			session.FlashError(w, r, "Unexpected error: couldn't get CurrentUser")
		}

		// Is the current viewer shy?
		var isShy = currentUser.IsShy()

		// Get the page of photos.
		pager := &models.Pagination{
			Page:    1,
			PerPage: config.PageSizeSiteGallery,
			Sort:    sort,
		}
		pager.ParsePage(r)
		photos, _ := models.PaginateGalleryPhotos(currentUser, models.Gallery{
			Explicit:   filterExplicit,
			Visibility: filterVisibility,
			AdminView:  adminView,
			ShyView:    isShy,
		}, pager)

		// Bulk load the users associated with these photos.
		var userIDs = []uint64{}
		for _, photo := range photos {
			userIDs = append(userIDs, photo.UserID)
		}
		userMap, err := models.MapUsers(currentUser, userIDs)
		if err != nil {
			session.FlashError(w, r, "Failed to MapUsers: %s", err)
		}

		// Get Likes information about these photos.
		var photoIDs = []uint64{}
		for _, p := range photos {
			photoIDs = append(photoIDs, p.ID)
		}
		likeMap := models.MapLikes(currentUser, "photos", photoIDs)
		commentMap := models.MapCommentCounts("photos", photoIDs)

		var vars = map[string]interface{}{
			"IsSiteGallery": true,
			"Photos":        photos,
			"UserMap":       userMap,
			"LikeMap":       likeMap,
			"CommentMap":    commentMap,
			"Pager":         pager,
			"ViewStyle":     viewStyle,

			// Search filters
			"Sort":             sort,
			"FilterExplicit":   filterExplicit,
			"FilterVisibility": filterVisibility,
			"AdminView":        adminView,

			// Is the current user shy?
			"IsShyUser": isShy,
		}

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