// Command adminctl performs the operations that deliberately have no HTTP
// surface.
//
//	adminctl staff-add --email=you@example.com --name="You" --password=...
//
// There is no staff signup endpoint. A licensing authority that can be joined
// over the internet is not one.
package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"strings"
	"time"

	"gitea.hostxtra.co.uk/mrhid6/vantage/admin/internal/config"
	"gitea.hostxtra.co.uk/mrhid6/vantage/admin/internal/db"
	"gitea.hostxtra.co.uk/mrhid6/vantage/admin/internal/models"
	"github.com/google/uuid"
	"github.com/joho/godotenv"
	"golang.org/x/crypto/bcrypt"
)

func main() {
	godotenv.Load()
	if len(os.Args) < 2 {
		fmt.Fprintln(os.Stderr, "usage: adminctl staff-add")
		os.Exit(2)
	}

	cfg, err := config.Load()
	if err != nil {
		fatal("configuration: %v", err)
	}
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()
	if err := db.Connect(ctx, cfg); err != nil {
		fatal("database: %v", err)
	}

	switch os.Args[1] {
	case "staff-add":
		staffAdd(ctx, os.Args[2:])
	default:
		fmt.Fprintln(os.Stderr, "usage: adminctl staff-add")
		os.Exit(2)
	}
}

func staffAdd(ctx context.Context, args []string) {
	fs := flag.NewFlagSet("staff-add", flag.ExitOnError)
	email := fs.String("email", "", "staff email (required)")
	name := fs.String("name", "", "display name")
	password := fs.String("password", "", "password, at least 12 characters (required)")
	fs.Parse(args)

	if *email == "" || len(*password) < 12 {
		fatal("--email and a --password of at least 12 characters are required")
	}

	hash, err := bcrypt.GenerateFromPassword([]byte(*password), 12)
	if err != nil {
		fatal("hash: %v", err)
	}

	u := models.StaffUser{
		UserID:       uuid.NewString(),
		Email:        strings.ToLower(strings.TrimSpace(*email)),
		PasswordHash: string(hash),
		Name:         *name,
		CreatedAt:    time.Now().UTC(),
	}
	if _, err := db.Admin("staff_users").InsertOne(ctx, u); err != nil {
		fatal("create staff user: %v", err)
	}
	fmt.Printf("created staff user %s\n", u.Email)
}

func fatal(format string, a ...any) {
	fmt.Fprintf(os.Stderr, format+"\n", a...)
	os.Exit(1)
}
