package services

import (
	"fmt"

	"git.linuxforward.com/byop/byop-engine/dbstore"
	"git.linuxforward.com/byop/byop-engine/models"
	"golang.org/x/crypto/bcrypt"
)

// UserService handles user-related business logic
type UserService struct {
	store *dbstore.UserStore
}

// NewUserService creates a new UserService
func NewUserService(store *dbstore.UserStore) *UserService {
	return &UserService{store: store}
}

// CreateUser creates a new user with hashed password
func (s *UserService) CreateUser(user *models.User) error {
	// Hash the password
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	if err != nil {
		return fmt.Errorf("failed to hash password: %w", err)
	}
	user.Password = string(hashedPassword)

	// Save the user to the store
	return s.store.Create(user)
}

// GetUser retrieves a user by ID
func (s *UserService) GetUser(id string) (*models.User, error) {
	user, err := s.store.GetByID(id)
	if err != nil {
		return nil, fmt.Errorf("failed to get user: %w", err)
	}
	return user, nil
}

// UpdateUser updates an existing user
func (s *UserService) UpdateUser(user *models.User) error {
	// Hash the password if it's provided
	if user.Password != "" {
		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
		if err != nil {
			return fmt.Errorf("failed to hash password: %w", err)
		}
		user.Password = string(hashedPassword)
	}

	// Update the user in the store
	return s.store.Update(user)
}

// DeleteUser deletes a user by ID
func (s *UserService) DeleteUser(id string) error {
	return s.store.Delete(id)
}

// ListUsers retrieves all users with optional filtering
func (s *UserService) ListUsers(filter map[string]interface{}) ([]*models.User, error) {
	users, err := s.store.List(filter)
	if err != nil {
		return nil, fmt.Errorf("failed to list users: %w", err)
	}
	return users, nil
}

// AuthenticateUser checks if the provided credentials are valid
func (s *UserService) AuthenticateUser(username, password string) (*models.User, error) {
	user, err := s.store.GetByUsername(username)
	if err != nil {
		return nil, fmt.Errorf("failed to get user: %w", err)
	}
	if user == nil {
		return nil, fmt.Errorf("user not found")
	}

	// Compare the provided password with the hashed password
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
		return nil, fmt.Errorf("invalid password")
	}

	return user, nil
}

// GetUserDeployments retrieves all deployments for a user
func (s *UserService) GetUserDeployments(userID string) ([]*models.Deployment, error) {
	user, err := s.store.GetByID(userID)
	if err != nil {
		return nil, fmt.Errorf("failed to get user: %w", err)
	}
	if user == nil {
		return nil, fmt.Errorf("user not found")
	}

	deployments, err := s.store.ListDeploymentsByUserID(user.ID)
	if err != nil {
		return nil, fmt.Errorf("failed to list deployments: %w", err)
	}
	return deployments, nil
}
