package db

import (
	"fmt"
	"time"

	"inboxer/src/internal/auth"
)

// DatabaseOTPStore implements auth.OTPStore using the database
type DatabaseOTPStore struct {
	db *Database
}

// NewDatabaseOTPStore creates a new database OTP store
func NewDatabaseOTPStore(db *Database) *DatabaseOTPStore {
	return &DatabaseOTPStore{db: db}
}

// StoreOTP stores an OTP hash and expiry for the given email
func (s *DatabaseOTPStore) StoreOTP(email, otpHash string, expiry time.Time) error {
	// First, ensure user exists
	_, err := s.db.GetUserByEmail(email)
	if err != nil {
		// User doesn't exist, create them
		_, err = s.db.CreateUser(email)
		if err != nil {
			return fmt.Errorf("failed to create user: %w", err)
		}
	}

	// Update OTP for existing user
	err = s.db.UpdateUserOTP(email, otpHash, expiry)
	if err != nil {
		return fmt.Errorf("failed to store OTP: %w", err)
	}

	return nil
}

// GetOTP retrieves the OTP hash and expiry for the given email
func (s *DatabaseOTPStore) GetOTP(email string) (string, time.Time, error) {
	user, err := s.db.GetUserByEmail(email)
	if err != nil {
		return "", time.Time{}, fmt.Errorf("user not found: %w", err)
	}

	if user.HashedOTP == "" || user.OTPExpiry == nil {
		return "", time.Time{}, fmt.Errorf("OTP not found for email: %s", email)
	}

	return user.HashedOTP, *user.OTPExpiry, nil
}

// DeleteOTP removes the OTP for the given email
func (s *DatabaseOTPStore) DeleteOTP(email string) error {
	err := s.db.ClearUserOTP(email)
	if err != nil {
		return fmt.Errorf("failed to delete OTP: %w", err)
	}
	return nil
}

// Ensure DatabaseOTPStore implements auth.OTPStore
var _ auth.OTPStore = (*DatabaseOTPStore)(nil)