package repository

import (
	"context"
	"lune/talentscale/internal/domain"
	"time"

	"github.com/jackc/pgx/v5/pgxpool"
)

type postgresAuthRepository struct {
	db *pgxpool.Pool
}

func NewPostgresAuthRepository(db *pgxpool.Pool) domain.AuthUtilRepository {
	return &postgresAuthRepository{db: db}
}

func (r *postgresAuthRepository) CreateSession(ctx context.Context, s *domain.UserSession) error {
	query := `INSERT INTO user_sessions (user_id, session_token, ip_address, user_agent, is_active, last_activity, expires_at, created_at)
	          VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`
	_, err := r.db.Exec(ctx, query, s.UserID, s.SessionToken, s.IPAddress, s.UserAgent, s.IsActive, s.LastActivity, s.ExpiresAt, s.CreatedAt)
	return err
}

func (r *postgresAuthRepository) GetSessionByToken(ctx context.Context, token string) (*domain.UserSession, error) {
	query := `SELECT id, user_id, session_token, ip_address, user_agent, is_active, last_activity, expires_at, created_at
	          FROM user_sessions WHERE session_token = $1`
	var s domain.UserSession
	err := r.db.QueryRow(ctx, query, token).Scan(&s.ID, &s.UserID, &s.SessionToken, &s.IPAddress, &s.UserAgent, &s.IsActive, &s.LastActivity, &s.ExpiresAt, &s.CreatedAt)
	if err != nil {
		return nil, err
	}
	return &s, nil
}

func (r *postgresAuthRepository) DeactivateSession(ctx context.Context, token string) error {
	query := `UPDATE user_sessions SET is_active = FALSE WHERE session_token = $1`
	_, err := r.db.Exec(ctx, query, token)
	return err
}

func (r *postgresAuthRepository) CreatePasswordReset(ctx context.Context, pr *domain.PasswordReset) error {
	query := `INSERT INTO password_resets (user_id, token, expired_at, created_at)
	          VALUES ($1, $2, $3, $4)`
	_, err := r.db.Exec(ctx, query, pr.UserID, pr.Token, pr.ExpiredAt, pr.CreatedAt)
	return err
}

func (r *postgresAuthRepository) GetPasswordResetByToken(ctx context.Context, token string) (*domain.PasswordReset, error) {
	query := `SELECT id, user_id, token, expired_at, used_at, created_at
	          FROM password_resets WHERE token = $1`
	var pr domain.PasswordReset
	err := r.db.QueryRow(ctx, query, token).Scan(&pr.ID, &pr.UserID, &pr.Token, &pr.ExpiredAt, &pr.UsedAt, &pr.CreatedAt)
	if err != nil {
		return nil, err
	}
	return &pr, nil
}

func (r *postgresAuthRepository) MarkPasswordResetUsed(ctx context.Context, token string) error {
	query := `UPDATE password_resets SET used_at = $1 WHERE token = $2`
	_, err := r.db.Exec(ctx, query, time.Now(), token)
	return err
}
