package account

import (
	"net/http"
	"strconv"

	"git.kirsle.net/apps/gosocial/pkg/config"
	"git.kirsle.net/apps/gosocial/pkg/models"
	"git.kirsle.net/apps/gosocial/pkg/session"
	"git.kirsle.net/apps/gosocial/pkg/templates"
)

// Search controller.
func Search() http.HandlerFunc {
	tmpl := templates.Must("account/search.html")

	// Whitelist for ordering options.
	var sortWhitelist = []string{
		"last_login_at desc",
		"created_at desc",
		"username",
		"lower(name)",
	}

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Search filters.
		var (
			isCertified   = r.FormValue("certified")
			username      = r.FormValue("username") // email or username
			gender        = r.FormValue("gender")
			orientation   = r.FormValue("orientation")
			maritalStatus = r.FormValue("marital_status")
			sort          = r.FormValue("sort")
			sortOK        bool
			ageMin        int
			ageMax        int
		)

		ageMin, _ = strconv.Atoi(r.FormValue("age_min"))
		ageMax, _ = strconv.Atoi(r.FormValue("age_max"))
		if ageMin > ageMax {
			ageMin, ageMax = ageMax, ageMin
		}

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

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

		// Default
		if isCertified == "" {
			isCertified = "true"
		}

		pager := &models.Pagination{
			PerPage: config.PageSizeMemberSearch,
			Sort:    sort,
		}
		pager.ParsePage(r)

		users, err := models.SearchUsers(currentUser.ID, &models.UserSearch{
			EmailOrUsername: username,
			Gender:          gender,
			Orientation:     orientation,
			MaritalStatus:   maritalStatus,
			Certified:       isCertified == "true",
			AgeMin:          ageMin,
			AgeMax:          ageMax,
		}, pager)
		if err != nil {
			session.FlashError(w, r, "Couldn't search users: %s", err)
		}

		var vars = map[string]interface{}{
			"Users": users,
			"Pager": pager,
			"Enum":  config.ProfileEnums,

			// Search filter values.
			"Certified":       isCertified,
			"Gender":          gender,
			"Orientation":     orientation,
			"MaritalStatus":   maritalStatus,
			"EmailOrUsername": username,
			"AgeMin":          ageMin,
			"AgeMax":          ageMax,
			"Sort":            sort,
		}

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