package main

import (
	"encoding/json"
	"io"
	"log/slog"
	"net/http"
	"os"
	"time"
	"xoxo-webserver/internal/cronjob"
	"xoxo-webserver/internal/domain/db"
	"xoxo-webserver/internal/env"
	"xoxo-webserver/internal/middleware"
	"xoxo-webserver/internal/service"
)

func main() {
	go startUpdateQuoteJob()

	sMux := http.NewServeMux()
	sMux.HandleFunc("GET /api/quote", middleware.Log(getQuote))
	sMux.HandleFunc("GET /api/health", getHealth)
	addr := env.GetOrDefault("XOXO_WEBSERVER_ADDR", "localhost:3333")
	slog.Info("Web server listening...", "address", addr)
	err := http.ListenAndServe(addr, sMux)
	slog.Error("Web server stopped", "error", err)
	os.Exit(1)
}

func startUpdateQuoteJob() {
	interval := time.Second * time.Duration(env.GetOrDefaultInt("XOXO_WEBSERVER_JOB_INTERVAL", 10))
	cronjob.Start(interval, func(utc time.Time) {
		fTime := utc.Format("15:04:05.000")
		slog.Info("Executing job", "Time", fTime)
		ok, _ := db.TryToLockJobLogTableAndCreateEntry(utc, interval)
		if !ok {
			slog.Info("Skipping job iteration as lock could not be retrieved or job was executed too soon")
			return
		}
		quote, err := service.GetRandomQuote()
		if err == nil {
			err = db.SetNewQuote(quote)
			if err == nil {
				slog.Info("New quote was set", "quote", quote.Quote)
			}
		}
	})
}

func getHealth(w http.ResponseWriter, _ *http.Request) {
	w.WriteHeader(http.StatusOK)
}

func getQuote(w http.ResponseWriter, _ *http.Request) {
	q, err := db.GetQuote()
	if err != nil {
		_, _ = io.WriteString(w, err.Error())
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	_ = json.NewEncoder(w).Encode(q)
}
