<?php
require_once __DIR__ . '/config/database.php';
require_once __DIR__ . '/app/helpers/mailer.php';
require_once __DIR__ . '/app/helpers/csrf.php';

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

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    $action = $_GET['action'] ?? '';
    if ($action === 'forgot') {
        echo json_encode(['status' => 'error', 'message' => 'This endpoint requires a POST request. Use the forgot password form.']);
        exit;
    }
    http_response_code(405);
    echo json_encode(['status' => 'error', 'message' => 'Method not allowed']);
    exit;
}

$csrfToken = $_POST['_csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
if (!validateCsrfToken($csrfToken)) {
    http_response_code(419);
    echo json_encode(['status' => 'error', 'message' => 'Invalid or missing CSRF token']);
    exit;
}

function isValidPassword($password)
{
    return (bool) preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z\d]).{8,}$/', $password);
}

function isPasswordReused(PDO $pdo, $userId, $newPassword)
{
    $stmt = $pdo->prepare("
        SELECT password_hash
        FROM users
        WHERE id = ?
        LIMIT 1
    ");
    $stmt->execute([$userId]);
    $currentUser = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($currentUser && !empty($currentUser['password_hash']) && password_verify($newPassword, $currentUser['password_hash'])) {
        return true;
    }

    $stmt = $pdo->prepare("
        SELECT password_hash
        FROM user_password_history
        WHERE user_id = ?
        ORDER BY created_at DESC
        LIMIT 5
    ");
    $stmt->execute([$userId]);
    $history = $stmt->fetchAll(PDO::FETCH_ASSOC);

    foreach ($history as $row) {
        if (!empty($row['password_hash']) && password_verify($newPassword, $row['password_hash'])) {
            return true;
        }
    }

    return false;
}

try {
    $action = $_GET['action'] ?? '';

    if ($action === 'forgot') {
        $email = trim($_POST['email'] ?? '');

        if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            echo json_encode(['status' => 'error', 'message' => 'Please enter a valid email address.']);
            exit;
        }

        $stmt = $pdo->prepare("SELECT COUNT(*) FROM password_resets WHERE created_at > DATE_SUB(NOW(), INTERVAL 1 MINUTE) AND user_id = (SELECT id FROM users WHERE email = ?)");
        $stmt->execute([$email]);
        if ((int)$stmt->fetchColumn() >= 3) {
            echo json_encode(['status' => 'error', 'message' => 'Too many requests. Please wait before trying again.']);
            exit;
        }

        $stmt = $pdo->prepare("SELECT id, email, name FROM users WHERE email = ?");
        $stmt->execute([$email]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$user) {
            echo json_encode(['status' => 'success', 'message' => 'If the email exists, a reset link has been sent.']);
            exit;
        }

        $token = bin2hex(random_bytes(32));
        $tokenHash = hash('sha256', $token);
        $expiresAt = date('Y-m-d H:i:s', strtotime('+1 hour'));

        $pdo->prepare("DELETE FROM password_resets WHERE user_id = ?")
            ->execute([$user['id']]);

        $stmt = $pdo->prepare("
            INSERT INTO password_resets (user_id, token_hash, expires_at)
            VALUES (?, ?, ?)
        ");
        $stmt->execute([$user['id'], $tokenHash, $expiresAt]);

        $baseUrl = rtrim((string)(getenv('FLEET_APP_URL') ?: (((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'])), '/');

        $resetLink = $baseUrl . '/reset_password_page.php?token=' . urlencode($token);
        $safeName = htmlspecialchars((string)($user['name'] ?? 'User'), ENT_QUOTES, 'UTF-8');
        $safeLink = htmlspecialchars($resetLink, ENT_QUOTES, 'UTF-8');

        sendMail((string)$user['email'], 'Password reset request', "
            <div style=\"font-family:Arial,sans-serif;color:#102033;line-height:1.55;\">
                <h2>Password reset request</h2>
                <p>Hello {$safeName},</p>
                <p>Use the link below to reset your Fleet Operations password. This link expires in 1 hour.</p>
                <p><a href=\"{$safeLink}\" style=\"background:#1d4ed8;color:#fff;padding:10px 14px;text-decoration:none;border-radius:6px;\">Reset Password</a></p>
                <p style=\"color:#667085;font-size:12px;\">If you did not request this, you can ignore this message.</p>
            </div>
        ");

        echo json_encode([
            'status' => 'success',
            'message' => 'If the email exists, a reset link has been sent.'
        ]);
        exit;
    }

    if ($action === 'reset') {
        $token = trim($_POST['token'] ?? '');
        $password = $_POST['password'] ?? '';
        $confirmPassword = $_POST['confirm_password'] ?? '';

        if ($token === '' || $password === '' || $confirmPassword === '') {
            echo json_encode(['status' => 'error', 'message' => 'All fields are required.']);
            exit;
        }

        if ($password !== $confirmPassword) {
            echo json_encode(['status' => 'error', 'message' => 'Passwords do not match.']);
            exit;
        }

        if (!isValidPassword($password)) {
            echo json_encode([
                'status' => 'error',
                'message' => 'Password must be at least 8 characters and include uppercase, lowercase, number, and special character.'
            ]);
            exit;
        }

        $tokenHash = hash('sha256', $token);

        $stmt = $pdo->prepare("
            SELECT user_id
            FROM password_resets
            WHERE token_hash = ?
              AND expires_at > NOW()
            LIMIT 1
        ");
        $stmt->execute([$tokenHash]);
        $reset = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$reset) {
            echo json_encode(['status' => 'error', 'message' => 'Invalid or expired reset token.']);
            exit;
        }

        if (isPasswordReused($pdo, $reset['user_id'], $password)) {
            echo json_encode([
                'status' => 'error',
                'message' => 'You cannot reuse a previous password.'
            ]);
            exit;
        }

        $pdo->beginTransaction();

        try {
            $stmt = $pdo->prepare("
                SELECT password_hash
                FROM users
                WHERE id = ?
                LIMIT 1
            ");
            $stmt->execute([$reset['user_id']]);
            $currentUser = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($currentUser && !empty($currentUser['password_hash'])) {
                $stmt = $pdo->prepare("
                    INSERT INTO user_password_history (user_id, password_hash)
                    VALUES (?, ?)
                ");
                $stmt->execute([$reset['user_id'], $currentUser['password_hash']]);
            }

            $newPasswordHash = password_hash($password, PASSWORD_DEFAULT);

            $pdo->prepare("UPDATE users SET password_hash = ? WHERE id = ?")
                ->execute([$newPasswordHash, $reset['user_id']]);

            $pdo->prepare("DELETE FROM password_resets WHERE user_id = ?")
                ->execute([$reset['user_id']]);

            $pdo->commit();
        } catch (Throwable $e) {
            $pdo->rollBack();
            throw $e;
        }

        echo json_encode(['status' => 'success', 'message' => 'Password updated successfully.']);
        exit;
    }

    echo json_encode(['status' => 'error', 'message' => 'Invalid action.']);
    exit;
} catch (Throwable $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    http_response_code(500);
    echo json_encode([
        'status' => 'error',
        'message' => 'Server error: ' . $e->getMessage()
    ]);
    exit;
}
