package calls

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"

	"github.com/google/uuid"
	b "streifling.com/jason/cpolis/cmd/backend"
)

func incrementClicks(db *b.DB, a *b.Article) error {
	a.Clicks++
	if err := db.UpdateAttributes(&b.Attribute{Table: "articles", ID: a.ID, AttName: "clicks", Value: a.Clicks}); err != nil {
		return fmt.Errorf("error updating click attribute of article %v: %v", a.ID, err)
	}

	if a.IsInIssue {
		issue, err := db.GetArticle(a.IssueID)
		if err != nil {
			return fmt.Errorf("error getting issue %v: %v", a.IssueID, err)
		}

		issue.Clicks++
		if err := db.UpdateAttributes(&b.Attribute{Table: "articles", ID: issue.ID, AttName: "clicks", Value: issue.Clicks}); err != nil {
			return fmt.Errorf("error updating click attribute of issue %v: %v", issue.ID, err)
		}
	}

	return nil
}

func ServeArticle(c *b.Config, db *b.DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if !tokenIsVerified(w, r, c) {
			return
		}

		uuidString := r.PathValue("uuid")
		uuid, err := uuid.Parse(uuidString)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		article, err := db.GetArticleByUUID(uuid)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		if !article.Published {
			return
		}

		articlePath := filepath.Join(c.ArticleDir, fmt.Sprint(article.UUID, ".md"))
		contentBytes, err := os.ReadFile(articlePath)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		content, err := b.ConvertToHTML(string(contentBytes))
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		if err = incrementClicks(db, article); err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		if _, err = fmt.Fprint(w, content); err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}
}

func ServeClicks(db *b.DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		uuid, err := uuid.Parse(r.PathValue("uuid"))
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		article, err := db.GetArticleByUUID(uuid)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		if _, err = fmt.Fprint(w, article.Clicks); err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}
}