<?php
// send-otp.php — Generates and emails a 6-digit OTP for Dabil
//
// Expects POST: email (required), name (optional), purpose (optional:
// 'signup' | 'login' | 'password_reset', default 'signup')
//
// Returns JSON: { success: bool, message: string }

header('Content-Type: application/json');

require_once __DIR__ . '/config/db.php';
require_once __DIR__ . '/mailer.php';

const OTP_LENGTH          = 6;
const OTP_EXPIRY_MINUTES  = 10;
const OTP_RESEND_COOLDOWN = 60; // seconds

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'message' => 'Method not allowed.']);
    exit;
}

$email   = trim($_POST['email'] ?? '');
$name    = trim($_POST['name'] ?? '');
$purpose = trim($_POST['purpose'] ?? 'signup');

$allowedPurposes = ['signup', 'login', 'password_reset'];
if (!in_array($purpose, $allowedPurposes, true)) {
    $purpose = 'signup';
}

if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
    http_response_code(422);
    echo json_encode(['success' => false, 'message' => 'A valid email address is required.']);
    exit;
}

try {
    // --- Signup-specific check: don't issue OTPs for emails already registered ---
    if ($purpose === 'signup') {
        $stmt = $pdo->prepare('SELECT id FROM users WHERE email = :email LIMIT 1');
        $stmt->execute(['email' => $email]);
        if ($stmt->fetch()) {
            http_response_code(409);
            echo json_encode(['success' => false, 'message' => 'An account with this email already exists.']);
            exit;
        }
    }

    // --- Rate limit: prevent spamming the resend button ---
    $stmt = $pdo->prepare(
        'SELECT created_at FROM otp_codes
         WHERE email = :email AND purpose = :purpose
         ORDER BY created_at DESC LIMIT 1'
    );
    $stmt->execute(['email' => $email, 'purpose' => $purpose]);
    $last = $stmt->fetch();

    if ($last) {
        $secondsSinceLast = time() - strtotime($last['created_at']);
        if ($secondsSinceLast < OTP_RESEND_COOLDOWN) {
            $wait = OTP_RESEND_COOLDOWN - $secondsSinceLast;
            http_response_code(429);
            echo json_encode([
                'success' => false,
                'message' => "Please wait {$wait} seconds before requesting another code.",
            ]);
            exit;
        }
    }

    // --- Generate a cryptographically secure 6-digit code ---
    $otpCode = (string) random_int(100000, 999999);

    // --- Invalidate any previous unused codes for this email/purpose ---
    $stmt = $pdo->prepare(
        'UPDATE otp_codes SET is_used = 1
         WHERE email = :email AND purpose = :purpose AND is_used = 0'
    );
    $stmt->execute(['email' => $email, 'purpose' => $purpose]);

    // --- Store the new code ---
    $expiresAt = date('Y-m-d H:i:s', time() + OTP_EXPIRY_MINUTES * 60);

    $stmt = $pdo->prepare(
        'INSERT INTO otp_codes (email, otp_code, purpose, attempts, is_used, expires_at, created_at)
         VALUES (:email, :otp_code, :purpose, 0, 0, :expires_at, NOW())'
    );
    $stmt->execute([
        'email'      => $email,
        'otp_code'   => $otpCode,
        'purpose'    => $purpose,
        'expires_at' => $expiresAt,
    ]);

    // --- Send the email ---
    $subjectMap = [
        'signup'         => 'Verify your email — Dabil',
        'login'          => 'Your login code — Dabil',
        'password_reset' => 'Reset your password — Dabil',
    ];

    $result = send_mail(
        $email,
        $name,
        $subjectMap[$purpose],
        otp_email_body($name, $otpCode, OTP_EXPIRY_MINUTES)
    );

    if (!$result['success']) {
        // Roll back so the user can retry cleanly.
        $stmt = $pdo->prepare(
            'DELETE FROM otp_codes WHERE email = :email AND otp_code = :otp_code AND purpose = :purpose'
        );
        $stmt->execute(['email' => $email, 'otp_code' => $otpCode, 'purpose' => $purpose]);

        http_response_code(502);
        echo json_encode(['success' => false, 'message' => 'Could not send verification email. Please try again.']);
        exit;
    }

    echo json_encode([
        'success' => true,
        'message' => 'A 6-digit verification code has been sent to ' . $email . '.',
        'expires_in' => OTP_EXPIRY_MINUTES * 60,
    ]);

} catch (PDOException $e) {
    http_response_code(500);
    echo json_encode(['success' => false, 'message' => 'Something went wrong. Please try again.']);
}
