package postgres

import (
	"time"

	"github.com/jmoiron/sqlx"
	"github.com/ajaxray/geek-life/model"
)

// UserRepository implements the user repository interface for PostgreSQL
type UserRepository struct {
	db *sqlx.DB
}

// NewUserRepository creates a new user repository
func NewUserRepository(db *sqlx.DB) *UserRepository {
	return &UserRepository{db: db}
}

// GetByID retrieves a user by ID
func (r *UserRepository) GetByID(id int64) (*model.User, error) {
	var user model.User
	query := `SELECT id, tenant_id, username, email, password_hash, created_at, updated_at 
			  FROM users WHERE id = $1`
	err := r.db.Get(&user, query, id)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// GetByUsername retrieves a user by username within a tenant
func (r *UserRepository) GetByUsername(tenantID int64, username string) (*model.User, error) {
	var user model.User
	query := `SELECT id, tenant_id, username, email, password_hash, created_at, updated_at 
			  FROM users WHERE tenant_id = $1 AND username = $2`
	err := r.db.Get(&user, query, tenantID, username)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// GetByEmail retrieves a user by email within a tenant
func (r *UserRepository) GetByEmail(tenantID int64, email string) (*model.User, error) {
	var user model.User
	query := `SELECT id, tenant_id, username, email, password_hash, created_at, updated_at 
			  FROM users WHERE tenant_id = $1 AND email = $2`
	err := r.db.Get(&user, query, tenantID, email)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// Create creates a new user
func (r *UserRepository) Create(tenantID int64, username, email, passwordHash string) (*model.User, error) {
	user := &model.User{
		TenantID:     tenantID,
		Username:     username,
		Email:        email,
		PasswordHash: passwordHash,
		CreatedAt:    time.Now(),
		UpdatedAt:    time.Now(),
	}

	query := `INSERT INTO users (tenant_id, username, email, password_hash, created_at, updated_at) 
			  VALUES ($1, $2, $3, $4, $5, $6) RETURNING id`
	err := r.db.QueryRow(query, user.TenantID, user.Username, user.Email, user.PasswordHash, user.CreatedAt, user.UpdatedAt).Scan(&user.ID)
	if err != nil {
		return nil, err
	}

	return user, nil
}

// Update updates an existing user
func (r *UserRepository) Update(user *model.User) error {
	user.UpdatedAt = time.Now()
	query := `UPDATE users SET username = $1, email = $2, password_hash = $3, updated_at = $4 
			  WHERE id = $5`
	_, err := r.db.Exec(query, user.Username, user.Email, user.PasswordHash, user.UpdatedAt, user.ID)
	return err
}

// Delete deletes a user
func (r *UserRepository) Delete(user *model.User) error {
	query := `DELETE FROM users WHERE id = $1`
	_, err := r.db.Exec(query, user.ID)
	return err
}