package cli

import (
	"errors"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"

	"osaet/backend/internal/staticserver"
)

func runBuild(root string, args []string) error {
	fs := flag.NewFlagSet("build", flag.ContinueOnError)
	fs.SetOutput(os.Stderr)
	siteDir := fs.String("site-dir", defaultAstroDir, "Astro project directory")
	if err := fs.Parse(args); err != nil {
		return err
	}

	sitePath := *siteDir
	if !filepath.IsAbs(sitePath) {
		sitePath = filepath.Join(root, sitePath)
	}

	if _, err := os.Stat(filepath.Join(sitePath, "package.json")); err != nil {
		return fmt.Errorf("Astro project not found at %s; run from repo root", *siteDir)
	}

	cmd := exec.Command("npm", "run", "build")
	cmd.Dir = sitePath
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	return cmd.Run()
}

func runDev(root string, args []string) error {
	fs := flag.NewFlagSet("dev", flag.ContinueOnError)
	fs.SetOutput(os.Stderr)
	host := fs.String("host", "127.0.0.1", "host to bind")
	port := fs.String("port", "4321", "port to listen on")
	siteDir := fs.String("site-dir", defaultAstroDir, "Astro project directory")
	if err := fs.Parse(args); err != nil {
		return err
	}

	sitePath := *siteDir
	if !filepath.IsAbs(sitePath) {
		sitePath = filepath.Join(root, sitePath)
	}

	if _, err := os.Stat(filepath.Join(sitePath, "package.json")); err != nil {
		return fmt.Errorf("Astro project not found at %s; run `osaetctl init` first", *siteDir)
	}

	cmd := exec.Command("npm", "run", "dev", "--", "--host", *host, "--port", *port)
	cmd.Dir = sitePath
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	return cmd.Run()
}

func runServe(root string, args []string) error {
	fs := flag.NewFlagSet("serve", flag.ContinueOnError)
	fs.SetOutput(os.Stderr)
	host := fs.String("host", "127.0.0.1", "host to bind")
	port := fs.String("port", "4321", "port to listen on")
	dir := fs.String("dir", defaultBuildOutDir, "static output directory")
	if err := fs.Parse(args); err != nil {
		return err
	}

	staticDir := *dir
	if !filepath.IsAbs(staticDir) {
		staticDir = filepath.Join(root, staticDir)
	}

	if _, err := os.Stat(staticDir); err != nil {
		if errors.Is(err, os.ErrNotExist) {
			return fmt.Errorf("static directory %s does not exist; run `osaetctl build` first", *dir)
		}
		return err
	}
	return staticserver.Serve(staticDir, *host, *port)
}
