package database

import (
	"GoMembership/internal/constants"
	"GoMembership/internal/models"
	"GoMembership/pkg/logger"
	"crypto/rand"
	"encoding/base64"
	"time"

	"github.com/alexedwards/argon2id"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

var DB *gorm.DB

func Open(dbPath string, adminMail string) error {

	db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
	if err != nil {
		return err
	}
	if err := db.AutoMigrate(
		&models.User{},
		&models.SubscriptionModel{},
		&models.Membership{},
		&models.Consent{},
		&models.Verification{},
		&models.BankAccount{}); err != nil {
		logger.Error.Fatalf("Couldn't create database: %v", err)
		return err
	}
	DB = db

	logger.Info.Print("Opened DB")

	var count int64
	db.Model(&models.User{}).Count(&count)
	if count == 0 {
		admin, err := seedAdmin(adminMail)
		if err != nil {
			return err
		}
		result := db.Create(&admin)
		if result.Error != nil {
			return result.Error
		}
	}
	return nil
}

// TODO: Landing page to create an admin
func seedAdmin(userMail string) (*models.User, error) {
	passwordBytes := make([]byte, 12)
	_, err := rand.Read(passwordBytes)
	if err != nil {
		return nil, err
	}

	// Encode into a URL-safe base64 string
	password, err := base64.URLEncoding.EncodeToString(passwordBytes)[:12], nil
	if err != nil {
		return nil, err
	}
	hash, err := argon2id.CreateHash(password, argon2id.DefaultParams)
	if err != nil {
		return nil, err
	}

	logger.Error.Print("==============================================================")
	logger.Error.Printf("Admin Email: %v", userMail)
	logger.Error.Printf("Admin Password: %v", password)
	logger.Error.Print("==============================================================")

	return &models.User{
		FirstName:   "ad",
		LastName:    "min",
		DateOfBirth: time.Now(),
		Password:    hash,
		Address:     "Downhill 4",
		ZipCode:     "9999",
		City:        "TechTown",
		Email:       userMail,
		Status:      constants.ActiveStatus,
		RoleID:      constants.Roles.Editor,
	}, nil

}

func Close() error {
	logger.Info.Print("Closing  DB")
	db, err := DB.DB()
	if err != nil {
		return err
	}
	return db.Close()
}
