package main

import (
	"embed"
	"flag"
	"fmt"
	"io/fs"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"strings"
)

//go:embed dist/*
var distFS embed.FS

func main() {
	port := flag.Int("port", 1111, "port to listen on")
	apiTarget := flag.String("api", "http://localhost:8000", "backend API URL to proxy /api requests")
	flag.Parse()

	// Proxy for /api -> backend
	backendURL, err := url.Parse(*apiTarget)
	if err != nil {
		log.Fatalf("invalid api url: %v", err)
	}

	proxy := httputil.NewSingleHostReverseProxy(backendURL)
	originalDirector := proxy.Director
	proxy.Director = func(r *http.Request) {
		originalDirector(r)
		// Rewrite /api/... -> /...
		r.URL.Path = strings.TrimPrefix(r.URL.Path, "/api")
		if r.URL.Path == "" {
			r.URL.Path = "/"
		}
		r.Host = backendURL.Host
	}

	// Static files from embedded dist/
	distSub, err := fs.Sub(distFS, "dist")
	if err != nil {
		log.Fatalf("failed to open embedded dist: %v", err)
	}
	fileServer := http.FileServer(http.FS(distSub))

	mux := http.NewServeMux()

	// API proxy
	mux.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
		proxy.ServeHTTP(w, r)
	})

	// SPA: serve static files, fallback to index.html
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// Try to serve the file directly
		path := strings.TrimPrefix(r.URL.Path, "/")
		if path == "" {
			path = "index.html"
		}

		// Check if file exists in embedded FS
		if f, err := distSub.Open(path); err == nil {
			f.Close()
			fileServer.ServeHTTP(w, r)
			return
		}

		// Fallback to index.html for SPA routing
		indexFile, err := fs.ReadFile(distSub, "index.html")
		if err != nil {
			http.Error(w, "index.html not found", http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		w.Write(indexFile)
	})

	addr := fmt.Sprintf(":%d", *port)
	log.Printf("Serving on http://localhost%s", addr)
	log.Printf("API proxy -> %s", *apiTarget)

	if err := http.ListenAndServe(addr, mux); err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
}
