package server

import (
	"bytes"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"text/template"
	"time"

	"git.linuxit.ro/turos.robert/mynotes/cmds/webservice/types"
	"git.linuxit.ro/turos.robert/mynotes/lib/inout"
	"github.com/yuin/goldmark"
)

func Wildcard(w http.ResponseWriter, r *http.Request) {

	if r.Method == "GET" {
		base_dir := "./templates/"
		endpoint := strings.TrimPrefix(r.URL.Path, "/")
		//fmt.Println(endpoint)
		//fmt.Println(r.URL.Path)
		if endpoint == "" {
			//in cazul in care apelam root
			endpoint = "index.html"
		}
		path := filepath.Join(base_dir, endpoint)
		_, err := os.Stat(path)
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			w.Write(inout.FileToBytes("templates/error.tmpl"))
		}
		w.Write(inout.FileToBytes(path))
		return
	}

}

func API(w http.ResponseWriter, r *http.Request) {
	action := strings.TrimPrefix(r.URL.Path, "/api/")
	if r.Method == "POST" {
		//w.WriteHeader(http.StatusNotImplemented)
		//w.Write(fmt.Appendf(nil, "action not implemented: %s", action))
		switch action {
		case "save_note":
			r.ParseForm()
			n := types.Notita{}
			n.Titlu = r.Form.Get("titlu")
			n.Continut = r.Form.Get("notita")
			n.Folder = r.Form.Get("director")
			if n.Folder == "" {
				n.Folder = "default"
			}
			err := safeDirectory(n.Folder)
			if err != nil {
				w.WriteHeader(http.StatusBadRequest)
				fmt.Fprintf(w, "Error : %+v, %s", err, n.Folder)
				return
			}
			err = os.MkdirAll(filepath.Join("notes_folder", n.Folder), 0755)
			fmt.Println(n.Folder)
			if err != nil {
				w.WriteHeader(http.StatusBadRequest)
				fmt.Fprintf(w, "ParseForm error: %+v , %s", err, n.Folder)
				return
			}
			fisier := fmt.Sprintf("notita-%s.json", time.Now().Format("2006-01-02-150405.999999"))
			//fmt.Println(fisier, r.Form)
			//return

			err = inout.ObjToFile(filepath.Join("notes_folder", n.Folder, fisier), n, true)
			if err != nil {
				w.WriteHeader(http.StatusInternalServerError)
				fmt.Fprintf(w, "%+v", err)
				return
			}
			referinta := r.Referer()
			fmt.Println(referinta)
			if referinta != "" {
				http.Redirect(w, r, referinta, http.StatusSeeOther)
			} else {
				http.Redirect(w, r, "/index.html", http.StatusSeeOther)
			}
		}
	}
	w.WriteHeader(http.StatusMethodNotAllowed)
	w.Write([]byte("methoda nepermisa"))
}

func Notes(w http.ResponseWriter, r *http.Request, fisier string) {
	var buf bytes.Buffer
	notita := types.Notita{}
	err := inout.FileToObj(fisier, &notita)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte(WEB_ERR))
		fmt.Printf("%+v\n", err)
		return
	}
	if err := goldmark.Convert([]byte(notita.Continut), &buf); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte(WEB_ERR))
		fmt.Printf("%+v\n", err)
		return
	}
	notita.HTML = buf.String()
	tmpl := template.New("notita")
	_, err = tmpl.ParseFiles("./templates/notita.tmpl")
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte(WEB_ERR))
		fmt.Printf("%+v\n", err)
		return
	}
	err = tmpl.ExecuteTemplate(w, "notita.tmpl", notita)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte(WEB_ERR))
		fmt.Printf("%+v\n", err)
		return
	}
}

func safeDirectory(path string) error {
	path = filepath.Clean(path)
	if strings.HasPrefix(path, "..") || filepath.IsAbs(path) {
		return fmt.Errorf("Invalid Path")
	}
	return nil
}

func ListNotes(w http.ResponseWriter, r *http.Request) {

	if r.Method == "GET" {
		f := types.Folder{}
		err := buildFolderStructure("./notes_folder", &f)
		if err != nil {
			fmt.Println("EROARE la buildFolderStructure:", err)
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "%+v", err)
			return
		}
		tmpl := template.New("list_notes_test")
		_, err = tmpl.ParseFiles("./templates/list_notes.tmpl")
		if err != nil {
			fmt.Println("EROARE la buildFolderStructure:", err)
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "%+v", err)
			return
		}
		err = tmpl.ExecuteTemplate(w, "list_notes.tmpl", f)
		if err != nil {
			fmt.Println("EROARE la buildFolderStructure:", err)
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "%+v", err)
			return
		}
		return
	}
	w.WriteHeader(http.StatusMethodNotAllowed)
	w.Write([]byte("methoda nepermisa"))
}

func buildFolderStructure(path string, f *types.Folder) error {
	entries, err := os.ReadDir(path)
	if err != nil {
		return err
	}
	f.Nume = filepath.Clean(path)

	for _, entry := range entries {

		if entry.IsDir() {
			sub := types.Folder{}
			err = buildFolderStructure(filepath.Join(path, entry.Name()), &sub)
			if err != nil {
				return err
			}
			f.Subfoldere = append(f.Subfoldere, sub)
		} else {
			fisier := types.Fisier{
				Nume: entry.Name(),
				Path: filepath.Join(path, entry.Name()),
			}
			f.Fisiere = append(f.Fisiere, fisier)
		}
	}
	return nil
}
