package db

import (
	"fmt"

	"trustcontact/internal/auth"
	"trustcontact/internal/models"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

func Seed(database *gorm.DB) error {
	passwordHash, err := auth.HashPassword("password")
	if err != nil {
		return fmt.Errorf("hash seed password: %w", err)
	}

	seedUsers := []models.User{
		{
			Name:          "Admin User",
			Email:         "admin@example.com",
			Role:          models.RoleAdmin,
			EmailVerified: true,
			PasswordHash:  passwordHash,
			Properties: models.UserProperties{
				Lang: "en",
				Dark: true,
			},
		},
		{
			Name:          "Normal User",
			Email:         "user@example.com",
			Role:          models.RoleUser,
			EmailVerified: true,
			PasswordHash:  passwordHash,
			Properties: models.UserProperties{
				Lang: "it",
				Dark: false,
			},
		},
		{
			Name:          "Demo One",
			Email:         "demo1@example.com",
			Role:          models.RoleUser,
			EmailVerified: true,
			PasswordHash:  passwordHash,
			Properties: models.UserProperties{
				Lang: "en",
				Dark: true,
			},
		},
		{
			Name:          "Demo Two",
			Email:         "demo2@example.com",
			Role:          models.RoleUser,
			EmailVerified: true,
			PasswordHash:  passwordHash,
			Properties: models.UserProperties{
				Lang: "en",
				Dark: true,
			},
		},
		{
			Name:          "Demo Three",
			Email:         "demo3@example.com",
			Role:          models.RoleUser,
			EmailVerified: true,
			PasswordHash:  passwordHash,
			Properties: models.UserProperties{
				Lang: "en",
				Dark: true,
			},
		},
	}

	for _, user := range seedUsers {
		userID, err := upsertUser(database, user)
		if err != nil {
			return err
		}
		user.Properties.UserId = userID
		if err := upsertUserProperties(database, user.Properties, user.Email); err != nil {
			return err
		}
	}

	return nil
}

func upsertUser(database *gorm.DB, user models.User) (string, error) {
	result := database.Clauses(clause.OnConflict{
		Columns: []clause.Column{{Name: "email"}},
		DoUpdates: clause.AssignmentColumns([]string{
			"name",
			"role",
			"email_verified",
			"password_hash",
			"updated_at",
		}),
	}).Omit("Properties").Create(&user)
	if result.Error != nil {
		return "", fmt.Errorf("seed user %s: %w", user.Email, result.Error)
	}

	var persisted models.User
	if err := database.Select("id").Where("email = ?", user.Email).First(&persisted).Error; err != nil {
		return "", fmt.Errorf("load seeded user %s: %w", user.Email, err)
	}

	return persisted.ID, nil
}

func upsertUserProperties(database *gorm.DB, props models.UserProperties, userEmail string) error {
	result := database.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "user_id"}},
		DoNothing: true,
	}).Create(&props)
	if result.Error != nil {
		return fmt.Errorf("seed user properties %s: %w", userEmail, result.Error)
	}

	return nil
}
