package http

import (
	"net/http"
	"strconv"
	"strings"

	"git.arav.su/Arav/dwelling-home/pkg/mindflow"
	"git.arav.su/Arav/httpr"
)

type MindflowApiHandlers struct {
	db mindflow.Mindflow
}

func NewMindflowApiHandlers(db mindflow.Mindflow) *MindflowApiHandlers {
	return &MindflowApiHandlers{db: db}
}

func (h *MindflowApiHandlers) NewPost(w http.ResponseWriter, r *http.Request) {
	var post *mindflow.Post
	var category *mindflow.Category
	var err error

	if strings.Contains(r.Header.Get("Content-Type"), "application/x-www-form-urlencoded") {
		r.ParseForm()

		if r.FormValue("category") == "0" {
			category, err = mindflow.NewCategory(r.FormValue("new-category"))
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			category.ID, err = h.db.NewCategory(category)
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		} else {
			category = &mindflow.Category{}
			category.ID, _ = strconv.ParseInt(r.FormValue("category"), 10, 64)
		}

		post, err = mindflow.NewPost(*category, r.FormValue("title"), r.FormValue("body"))
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}

	if err = h.db.NewPost(post); err != nil {
		msg := strings.Join([]string{"Title:", r.FormValue("title"), "| Body:", r.FormValue("body")}, " ")
		Error(w, http.StatusInternalServerError, err.Error(), msg, r.Referer())
		return
	}

	http.Redirect(w, r, "/mindflow/admin", http.StatusMovedPermanently)
}

func (h *MindflowApiHandlers) EditPost(w http.ResponseWriter, r *http.Request) {
	var post *mindflow.Post
	var category mindflow.Category
	var err error

	if strings.Contains(r.Header.Get("Content-Type"), "application/x-www-form-urlencoded") {
		r.ParseForm()

		body := cleanupNewlines(r.FormValue("body"))

		category.ID, err = strconv.ParseInt(r.FormValue("category"), 10, 64)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		post, err = mindflow.NewPost(category, r.FormValue("title"), body)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		post.ID, _ = strconv.ParseInt(httpr.Param(r, "id"), 10, 64)
	}

	if err = h.db.EditPost(post); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func (h *MindflowApiHandlers) DeletePost(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.ParseInt(httpr.Param(r, "id"), 10, 64)
	if err := h.db.DeletePost(id); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func (h *MindflowApiHandlers) NewCategory(w http.ResponseWriter, r *http.Request) {
	var category *mindflow.Category
	var err error

	if strings.Contains(r.Header.Get("Content-Type"), "application/x-www-form-urlencoded") {
		r.ParseForm()

		category, err = mindflow.NewCategory(r.FormValue("name"))
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}

	_, err = h.db.NewCategory(category)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func (h *MindflowApiHandlers) EditCategory(w http.ResponseWriter, r *http.Request) {
	var category *mindflow.Category
	var err error

	if strings.Contains(r.Header.Get("Content-Type"), "application/x-www-form-urlencoded") {
		r.ParseForm()

		if r.FormValue("category") != "" || r.FormValue("category") != "0" {
			category, err = mindflow.NewCategory(r.FormValue("name"))
			if err != nil {
				http.Error(w, err.Error(), http.StatusBadRequest)
				return
			}
			category.ID, _ = strconv.ParseInt(httpr.Param(r, "id"), 10, 64)
		} else {
			http.Error(w, "empty category id passed", http.StatusBadRequest)
			return
		}
	}

	if err = h.db.EditCategory(category); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func (h *MindflowApiHandlers) DeleteCategory(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.ParseInt(httpr.Param(r, "id"), 10, 64)
	if err := h.db.DeleteCategory(id); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
