package handler

import (
	"fmt"
	"github.com/gorilla/mux"
	"log"
	"net/http"
	"status/config"
	"status/storage"
	"status/vpub"
	"status/web/session"
)

func serverError(w http.ResponseWriter, err error) {
	log.Println("[server error]", err)
	http.Error(w, fmt.Sprintf("server error: %s", err), http.StatusInternalServerError)
}

func notFound(w http.ResponseWriter) {
	http.Error(w, "Page Not Found", http.StatusNotFound)
}

func unauthorized(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, fmt.Sprintf("/login"), http.StatusFound)
}

type Handler struct {
	cfg     *config.Config
	mux     *mux.Router
	storage *storage.Storage
	sess    *session.Session
	vpub    vpub.Vpub
}

func protectClickJacking(w http.ResponseWriter) {
	w.Header().Set("X-Frame-Options", "DENY")
	w.Header().Set("Content-Security-Policy", "frame-ancestors 'none'")
}

func (h *Handler) getUser(r *http.Request) (string, error) {
	user, err := h.sess.Get(r)
	if err != nil {
		return "", err
	}
	return user, err
}

func New(cfg *config.Config, sess *session.Session, data *storage.Storage, v vpub.Vpub) (http.Handler, error) {
	router := mux.NewRouter()
	h := &Handler{
		cfg:     cfg,
		mux:     router,
		storage: data,
		sess:    sess,
		vpub:    v,
	}
	h.initTpl()

	router.HandleFunc("/", h.showIndexView).Methods(http.MethodGet)
	router.HandleFunc("/login", h.showLoginView).Methods(http.MethodGet)
	router.HandleFunc("/check-login", h.checkLogin).Methods(http.MethodPost)
	router.HandleFunc("/register", h.handleRegister)
	router.HandleFunc("/logout", h.logout).Methods(http.MethodGet)
	router.HandleFunc("/feed.atom", h.showFeedView).Methods(http.MethodGet)

	router.HandleFunc("/admin", h.showAdminView).Methods(http.MethodGet)
	router.HandleFunc("/activate-user", h.activateUser).Methods(http.MethodGet)
	router.HandleFunc("/delete-user", h.deleteUser).Methods(http.MethodGet)

	router.HandleFunc("/settings", h.showSettingsView).Methods(http.MethodGet)
	router.HandleFunc("/settings-update", h.updateSettings).Methods(http.MethodPost)
	router.HandleFunc("/forum-key", h.showKeyView).Methods(http.MethodGet)

	router.HandleFunc("/add", h.showNewStatusView).Methods(http.MethodGet)
	router.HandleFunc("/add", h.saveStatus).Methods(http.MethodPost)
	router.HandleFunc("/remove", h.handleRemoveStatus)
	router.HandleFunc("/edit", h.showEditStatusView).Methods(http.MethodGet)
	router.HandleFunc("/edit", h.updateStatus).Methods(http.MethodPost)
	router.HandleFunc("/current-status.js", h.showCurrentStatusJSView).Methods(http.MethodGet)
	router.HandleFunc("/current-status", h.showCurrentStatusView).Methods(http.MethodGet)
	router.HandleFunc("/manage", h.showManageView).Methods(http.MethodGet)
	router.HandleFunc("/tos", h.showTOSView).Methods(http.MethodGet)
	router.HandleFunc("/about/status-updater", h.showStatusUpdaterView).Methods(http.MethodGet)
	router.HandleFunc("/users/{user}.atom", h.showAtomView).Methods(http.MethodGet)
	router.HandleFunc("/users/{user}", h.showUserView).Methods(http.MethodGet)
	router.HandleFunc("/users/{user}/status", h.showUserStatusView).Methods(http.MethodGet)
	router.HandleFunc("/users/{user}/status.json", h.showUserStatusJSONView).Methods(http.MethodGet)
	router.HandleFunc("/statuses/{id}", h.showStatusView).Methods(http.MethodGet)

	router.HandleFunc("/users/{user}/badge.png", h.showUserStatusImageViewEmoji).Methods(http.MethodGet)
	router.PathPrefix("/assets/").Handler(
		http.StripPrefix("/assets/",
			http.FileServer(
				http.Dir(cfg.AssetsDir),
			),
		),
	)

	return router, nil
}
