package main

import (
	"log"
	"net/http"
	"os"
	"strings"
	"time"

	"report_go/config"
	"report_go/internal/db"
	"report_go/internal/handlers"
	"report_go/internal/repositories"
	"report_go/internal/response"
	"report_go/internal/services"
)

func main() {
	cfg, err := config.Load(resolveEnvPath())
	if err != nil {
		log.Fatalf("load config failed: %v", err)
	}

	mysqlDB, err := db.NewMySQL(cfg.MySQLDSN())
	if err != nil {
		log.Fatalf("mysql connect failed: %v", err)
	}
	defer mysqlDB.Close()

	repo := repositories.NewCaseReportRepository(mysqlDB)
	svc := services.NewCaseReportService(repo)
	h := handlers.NewCaseReportHandler(svc)

	mux := http.NewServeMux()

	mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		response.Success(w, "ok", map[string]any{
			"time": time.Now().Format("2006-01-02 15:04:05"),
		})
	})

	mux.HandleFunc("/api/reports/cases/list", h.List)
	mux.HandleFunc("/api/reports/cases/summary", h.Summary)

	server := &http.Server{
		Addr:              ":" + cfg.AppPort,
		Handler:           withCORS(withLogging(mux)),
		ReadHeaderTimeout: 10 * time.Second,
		ReadTimeout:       15 * time.Second,
		WriteTimeout:      30 * time.Second,
		IdleTimeout:       60 * time.Second,
	}

	log.Printf("sup-report-go started on :%s", cfg.AppPort)
	if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		log.Fatalf("server failed: %v", err)
	}
}

func resolveEnvPath() string {
	if v := strings.TrimSpace(os.Getenv("SUP_REPORT_ENV")); v != "" {
		return v
	}
	if v := strings.TrimSpace(os.Getenv("SUP_PRIVATE_PATH")); v != "" {
		return strings.TrimRight(v, `\\/`) + "/.env"
	}
	return "C:/web/sup_private/.env"
}

func withLogging(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		next.ServeHTTP(w, r)
		log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start))
	})
}

func withCORS(next http.Handler) http.Handler {
	allowedOrigins := allowedOriginsMap()

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		origin := strings.TrimSpace(r.Header.Get("Origin"))
		if origin != "" && allowedOrigins[origin] {
			w.Header().Set("Access-Control-Allow-Origin", origin)
			w.Header().Set("Vary", "Origin")
		}
		w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")

		if r.Method == http.MethodOptions {
			w.WriteHeader(http.StatusNoContent)
			return
		}

		next.ServeHTTP(w, r)
	})
}

func allowedOriginsMap() map[string]bool {
	raw := strings.TrimSpace(os.Getenv("SUP_ALLOWED_ORIGINS"))
	if raw == "" {
		raw = strings.Join([]string{
			"https://portal-viriyah.premium-care.in.th",
			"https://app.premium-care.in.th",
			"https://lab-app.premium-care.in.th",
			"http://localhost:3000",
			"http://127.0.0.1:3000",
		}, ",")
	}

	out := map[string]bool{}
	for _, part := range strings.Split(raw, ",") {
		part = strings.TrimSpace(part)
		if part != "" {
			out[part] = true
		}
	}
	return out
}
