package repository

import (
	"context"
	"time"

	"github.com/google/uuid"
	"github.com/jackc/pgx/v5/pgxpool"
	"github.com/ren/econ/backend/internal/models"
)

type UserRepository struct {
	db *pgxpool.Pool
}

func NewUserRepository(db *pgxpool.Pool) *UserRepository {
	return &UserRepository{db: db}
}

func (r *UserRepository) Create(ctx context.Context, user *models.Usuario) error {
	user.ID = uuid.New()
	user.CreadoEn = time.Now()
	user.Activo = true
	if user.Rol == "" {
		user.Rol = "estudiante"
	}

	query := `
		INSERT INTO usuarios (id, email, username, password_hash, nombre, rol, creado_en, activo)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
	`
	_, err := r.db.Exec(ctx, query,
		user.ID, user.Email, user.Username, user.PasswordHash, user.Nombre, user.Rol, user.CreadoEn, user.Activo)
	return err
}

func (r *UserRepository) GetByID(ctx context.Context, id uuid.UUID) (*models.Usuario, error) {
	query := `
		SELECT id, email, username, password_hash, nombre, rol, creado_en, ultimo_login, activo
		FROM usuarios WHERE id = $1
	`
	var user models.Usuario
	err := r.db.QueryRow(ctx, query, id).Scan(
		&user.ID, &user.Email, &user.Username, &user.PasswordHash, &user.Nombre,
		&user.Rol, &user.CreadoEn, &user.UltimoLogin, &user.Activo)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

func (r *UserRepository) GetByEmail(ctx context.Context, email string) (*models.Usuario, error) {
	query := `
		SELECT id, email, username, password_hash, nombre, rol, creado_en, ultimo_login, activo
		FROM usuarios WHERE email = $1
	`
	var user models.Usuario
	err := r.db.QueryRow(ctx, query, email).Scan(
		&user.ID, &user.Email, &user.Username, &user.PasswordHash, &user.Nombre,
		&user.Rol, &user.CreadoEn, &user.UltimoLogin, &user.Activo)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

func (r *UserRepository) GetByUsername(ctx context.Context, username string) (*models.Usuario, error) {
	query := `
		SELECT id, email, username, password_hash, nombre, rol, creado_en, ultimo_login, activo
		FROM usuarios WHERE username = $1
	`
	var user models.Usuario
	err := r.db.QueryRow(ctx, query, username).Scan(
		&user.ID, &user.Email, &user.Username, &user.PasswordHash, &user.Nombre,
		&user.Rol, &user.CreadoEn, &user.UltimoLogin, &user.Activo)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

func (r *UserRepository) List(ctx context.Context) ([]models.Usuario, error) {
	query := `
		SELECT id, email, username, password_hash, nombre, rol, creado_en, ultimo_login, activo
		FROM usuarios ORDER BY creado_en DESC
	`
	rows, err := r.db.Query(ctx, query)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var users []models.Usuario
	for rows.Next() {
		var user models.Usuario
		err := rows.Scan(
			&user.ID, &user.Email, &user.Username, &user.PasswordHash, &user.Nombre,
			&user.Rol, &user.CreadoEn, &user.UltimoLogin, &user.Activo)
		if err != nil {
			return nil, err
		}
		users = append(users, user)
	}
	return users, nil
}

func (r *UserRepository) Update(ctx context.Context, user *models.Usuario) error {
	query := `
		UPDATE usuarios SET email = $2, nombre = $3, rol = $4, activo = $5
		WHERE id = $1
	`
	_, err := r.db.Exec(ctx, query,
		user.ID, user.Email, user.Nombre, user.Rol, user.Activo)
	return err
}

func (r *UserRepository) Delete(ctx context.Context, id uuid.UUID) error {
	// Soft delete - set activo to false
	query := `UPDATE usuarios SET activo = false WHERE id = $1`
	_, err := r.db.Exec(ctx, query, id)
	return err
}

func (r *UserRepository) UpdateLastLogin(ctx context.Context, id uuid.UUID) error {
	query := `UPDATE usuarios SET ultimo_login = $2 WHERE id = $1`
	_, err := r.db.Exec(ctx, query, id, time.Now())
	return err
}
