package frontend

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"time"

	"github.com/gabriel-vasile/mimetype"
	"github.com/google/uuid"
	b "streifling.com/jason/cpolis/cmd/backend"
)

func UploadDocx(c *b.Config, db *b.DB, s map[string]*Session) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		session, err := ManageSession(w, r, c, s)
		if err != nil {
			http.Error(w, "Die Session ist abgelaufen. Bitte erneut anmelden.", http.StatusUnauthorized)
			return
		}

		file, fileHeader, err := r.FormFile("docx-upload")
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer file.Close()

		var buf bytes.Buffer
		if _, err = io.Copy(&buf, file); err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		mime := mimetype.Detect(buf.Bytes())
		if !mime.Is("application/vnd.openxmlformats-officedocument.wordprocessingml.document") {
			http.Error(w, "Die Datei ist kein DOCX Worddokument.", http.StatusBadRequest)
			return
		}

		docxFilepath := filepath.Join(os.TempDir(), fmt.Sprint(uuid.New(), ".docx"))
		if err = os.WriteFile(docxFilepath, buf.Bytes(), 0644); err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer os.Remove(docxFilepath)

		mdString, err := b.ConvertToMarkdown(c, docxFilepath)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		uuidName := uuid.New()
		mdFilepath := filepath.Join(c.ArticleDir, fmt.Sprint(uuidName, ".md"))
		if err = os.WriteFile(mdFilepath, mdString, 0644); err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		article := &b.Article{
			Created:   time.Now(),
			UUID:      uuidName,
			CreatorID: session.User.ID,
			Rejected:  true,
		}
		article.Title = fmt.Sprint(fileHeader.Filename, "-", article.UUID)

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

		if err = db.WriteArticleAuthors(id, []int64{session.User.ID}); err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		w.WriteHeader(http.StatusOK)
	}
}