package main

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

	"apps/backend/internal/config"

	"github.com/zeromicro/go-zero/core/conf"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"golang.org/x/crypto/bcrypt"
)

// seeder is intentionally explicit: a deployment must provide its own admin
// password rather than receiving a committed default credential.
func main() {
	configFile := flag.String("f", "etc/gateway.yaml", "config file")
	flag.Parse()

	var c config.Config
	conf.MustLoad(*configFile, &c)
	c.ApplyEnv()
	password := c.Seed.AdminPassword
	if len(password) < 12 || strings.Contains(password, "REPLACE_WITH") {
		panic("Seed.AdminPassword in gateway.yaml must be at least 12 characters")
	}
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI(c.Mongo.URI))
	if err != nil {
		panic(err)
	}
	defer client.Disconnect(context.Background())

	hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		panic(err)
	}
	now := time.Now().UTC().UnixNano()
	admin := bson.M{
		"uid":               int64(1_000_000),
		"tenant_id":         "default",
		"email":             "admin@haixun.local",
		"display_name":      "Harbor Admin",
		"roles":             []string{"admin", "member"},
		"status":            "active",
		"email_verified":    true,
		"email_verified_at": now,
		"invite_code":       "SEEDADMIN",
		"password_hash":     string(hash),
		"timezone":          "Asia/Taipei",
		"created_at":        now,
		"updated_at":        now,
	}
	db := client.Database(c.Mongo.Database)
	_, err = db.Collection("members").UpdateOne(ctx, bson.M{"uid": admin["uid"]}, bson.M{"$setOnInsert": admin}, options.Update().SetUpsert(true))
	if err != nil {
		panic(err)
	}
	_, err = db.Collection("counters").UpdateOne(ctx, bson.M{"_id": "member_uid"}, bson.M{"$setOnInsert": bson.M{"seq": int64(1_000_000)}}, options.Update().SetUpsert(true))
	if err != nil {
		panic(err)
	}
	fmt.Printf("seeded admin %s\n", strings.TrimSpace(admin["email"].(string)))
}
