package auth

import (
	"log"
	"time"

	"git.schreifuchs.ch/schreifuchs/ng-blog/internal/model"
	jwt "github.com/golang-jwt/jwt/v5"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

// Config defines a struct for configuration settings, often loaded from environment variables.
type Config struct {
	Secret        string        `env:"SECRET"`
	ValidDuration time.Duration `env:"VALID_DURATION"`
	AdminName     string        `env:"ADMIN_NAME"`
	AdminPassword string        `env:"ADMIN_PASSWORD"`
	DefaultRole   model.Role    `env:"DEFAULT_ROLE"`
}

// Service Represents a service with configuration and database connection.
type Service struct {
	cfg *Config
	db  *gorm.DB
}

// New creates a new Service instance, initializing a default admin user and saving it to the database.
func New(cfg *Config, db *gorm.DB) *Service {
	user := model.NewUser()
	var err error
	if user.Password, err = bcrypt.GenerateFromPassword([]byte(cfg.AdminName), 6); err != nil {
		log.Fatalf("Error while creating default user: %v", err)
	}
	user.Name = cfg.AdminName
	user.Role = model.RoleAdmin

	// add default user
	_ = db.Clauses(clause.OnConflict{DoNothing: true}).Save(&user).Error

	return &Service{
		cfg,
		db,
	}
}

// Claims struct represents JWT claims, including role and user ID, extending the standard jwt.RegisteredClaims.
type Claims struct {
	Role   model.Role `json:"rl"`
	UserID uint       `json:"uid"`
	jwt.RegisteredClaims
}

// Login struct represents user login credentials with a name and password.
type Login struct {
	Name     string `json:"name"`
	Password string `json:"Password"`
}

// LoginResponse Represents the response from a login endpoint, containing a JWT token.
type LoginResponse struct {
	Token string `json:"token"`
}
