package main

import (
	"html/template"
	"net/http"
	"os"
	"path"
	"strings"
	"time"
)

func getConfigFromEnv(item string) string {
	value := os.Getenv("CONFIG_ENVVAR")
	if value == "" {
		value = "ADDRESS,INITIALCOST,YEARLYCOST"
	}
	configArr := strings.Split(value, ",")

	// Check for expected length to prevent out-of-range panic
	if len(configArr) < 3 {
		logit("CONFIG_ENVVAR has less than 3 elements")
		return "NOTFOUND"
	}

	switch strings.ToLower(item) {
	case "address":
		return configArr[0]
	case "initialcost":
		return configArr[1]
	case "yearlycost":
		return configArr[2]
	default:
		return "NOTFOUND"
	}
}

func serveTemplate(w http.ResponseWriter, r *http.Request) {
	logit("Called URL: " + r.URL.Path)
	// wennn kein File angegeben ist: index.html
	if r.URL.Path == "/" {
		r.URL.Path = "/index.html"
	}
	lp := path.Join("templates", "layout.html")
	fp := path.Join("snippets", r.URL.Path)

	// Return a 404 if the template doesn't exist
	_, err := os.Stat(fp)
	if err != nil {
		if os.IsNotExist(err) {
			logit("URL not found: " + fp)
			fp = path.Join("snippets", "404.html")
		}
	}

	tmpl, err := template.ParseFiles(lp, fp)
	if err != nil {
		// Log the detailed error
		logit(err.Error())
		// Return a generic "Internal Server Error" message
		http.Error(w, http.StatusText(500), 500)
		return
	}

	var userName = getUserName(r)

	t := time.Now()
	var datetimestring = t.Format("20060102150405")
	var address = template.HTML(getConfigFromEnv("address"))
	var initialcost = getConfigFromEnv("initialcost")
	var yearlycost = getConfigFromEnv("yearlycost")
	var scales = getMyDevs(userName)
	var last_metrics []OneMetric

	query_values := r.URL.Query()

	if r.URL.Path == "/scales.html" {
		// wir holen noch die letzten Metriken
		for _, v := range scales {
			deveui := v
			readonly := false
			if strings.HasPrefix(deveui, "@") {
				deveui = deveui[1:]
				readonly = true
			}
			last_metric := getLastMetrics(deveui)
			last_metric.Readonly = readonly
			last_metrics = append(last_metrics, last_metric)
		}
	}

	data := struct {
		UserName       string
		DateTimeString string
		Address        template.HTML
		InitialCost    string
		YearlyCost     string
		Scales         []string
		LastMetrics    []OneMetric
		QueryValues    map[string][]string
	}{
		userName,
		datetimestring,
		address,
		initialcost,
		yearlycost,
		scales,
		last_metrics,
		query_values,
	}

	if err := tmpl.ExecuteTemplate(w, "layout", &data); err != nil {
		logit(err.Error())
		http.Error(w, http.StatusText(500), 500)
	}
}

func main() {
	initDB()
	defer closeDB()
	fs := http.FileServer(http.Dir("static"))
	http.Handle("/static/", http.StripPrefix("/static/", fs))
	http.Handle("/favicon.ico", fs)
	http.HandleFunc("/", serveTemplate)

	http.HandleFunc("/login", loginHandler)
	http.HandleFunc("/reset_password", resetPasswordHandler)
	http.HandleFunc("/set_password", setPasswordHandler)
	http.HandleFunc("/logout", logoutHandler)
	http.HandleFunc("/confirm", confirmHandler)
	http.HandleFunc("/metrics", metricsHandler)
	http.HandleFunc("/abocost", abocostHandler)
	http.HandleFunc("/lastmetrics", lastmetricsHandler)
	http.HandleFunc("/save_scale_settings", save_scale_settingsHandler)
	http.HandleFunc("/getstripepaymentintent", getstripepaymentintentHandler)
	http.HandleFunc("/stripewebhook", stripeWebhookHandler)
	http.HandleFunc("/checknodes", checkNodesHandler)

	logit("Starting Web Application...")
	http.ListenAndServe(":4000", nil)
	logit("Terminating Web Application...")
}
