<?php
// reset_password.php: Handles password reset confirmation for Ton Sui Mining
// Define TONSUI_LOADED constant to prevent direct access to session_init.php
define('TONSUI_LOADED', true);

// Include centralized session initialization
require_once __DIR__ . '/session_init.php';

header('Content-Type: application/json');
// Critical: Add cache control headers
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
// CRITICAL: Allow origin with credentials
// Reflect origin for credentialed requests (avoid wildcard when credentials used)
$allowed_origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
if (!empty($allowed_origin)) {
    header("Access-Control-Allow-Origin: $allowed_origin");
} else {
    $scheme = $_SERVER['REQUEST_SCHEME'] ?? 'https';
    $host = $_SERVER['HTTP_HOST'] ?? '';
    if (!empty($host)) {
        header('Access-Control-Allow-Origin: ' . $scheme . '://' . $host);
    }
}
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
header('Access-Control-Allow-Credentials: true');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

require_once 'db.php';
require_once 'auth.php';
require_once 'csrf.php';

function respond($success, $message, $data = null) {
    $response = ['success' => $success, 'message' => $message];
    if ($data !== null) {
        $response['data'] = $data;
    }
    echo json_encode($response);
    exit;
}

// Get POST data
$data = json_decode(file_get_contents('php://input'), true);
$token = trim($data['token'] ?? '');
$email = trim($data['email'] ?? '');
$password = $data['password'] ?? '';
$confirm_password = $data['confirm_password'] ?? '';

// Validate inputs
if (!$token || !$email || !$password || !$confirm_password) {
    respond(false, 'All fields are required.');
}

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    respond(false, 'Invalid email format.');
}

if ($password !== $confirm_password) {
    respond(false, 'Passwords do not match.');
}

if (strlen($password) < 8) {
    respond(false, 'Password must be at least 8 characters long.');
}

// Password complexity check
if (!preg_match('/[A-Z]/', $password) || 
    !preg_match('/[a-z]/', $password) || 
    !preg_match('/[0-9]/', $password)) {
    respond(false, 'Password must contain at least one uppercase letter, one lowercase letter, and one number.');
}

try {
    // Find the user
    $stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
    $stmt->execute([$email]);
    $user = $stmt->fetch();
    
    if (!$user) {
        respond(false, 'Invalid or expired reset link.');
    }
    
    // Check if password_reset_tokens table exists
    try {
        $checkTableStmt = $pdo->query("SHOW TABLES LIKE 'password_reset_tokens'");
        $tableExists = $checkTableStmt->rowCount() > 0;
        
        if (!$tableExists) {
            // Table doesn't exist, which means reset tokens aren't set up yet
            respond(false, 'Password reset system is not configured. Please contact support.');
        }
        
        // Verify token exists, belongs to this user, is not used, and is not expired
        $tokenStmt = $pdo->prepare('SELECT * FROM password_reset_tokens 
                                 WHERE token = ? AND user_id = ? AND used = 0 AND expires_at > NOW()');
        $tokenStmt->execute([$token, $user['id']]);
        $resetToken = $tokenStmt->fetch();
        
        if (!$resetToken) {
            respond(false, 'Invalid or expired reset link. Please request a new password reset.');
        }
    } catch (Exception $e) {
        error_log('Token verification error: ' . $e->getMessage());
        respond(false, 'Error verifying reset token. Please try again.');
    }
    
    // Update the password
    $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
    
    // Use a transaction to ensure both password update and token invalidation occur together
    $pdo->beginTransaction();
    
    try {
        // Update the password
        $updateStmt = $pdo->prepare('UPDATE users SET password = ? WHERE id = ?');
        $updateStmt->execute([$hashedPassword, $user['id']]);
        
        // Mark the token as used (tolerant of schema differences)
        $hasUsedAt = false;
        try {
            $col = $pdo->query("SHOW COLUMNS FROM password_reset_tokens LIKE 'used_at'");
            $hasUsedAt = $col && $col->rowCount() > 0;
        } catch (Exception $ie) {
            $hasUsedAt = false;
        }
        if ($hasUsedAt) {
            $markTokenStmt = $pdo->prepare('UPDATE password_reset_tokens SET used = 1, used_at = NOW() WHERE token = ?');
            $markTokenStmt->execute([$token]);
        } else {
            $markTokenStmt = $pdo->prepare('UPDATE password_reset_tokens SET used = 1 WHERE token = ?');
            $markTokenStmt->execute([$token]);
        }
        
        // Commit the transaction
        $pdo->commit();
        
        // Log the password reset event
        try {
            $logStmt = $pdo->prepare('INSERT INTO security_logs (event_type, user_id, ip_address, user_agent, created_at) 
                                     VALUES (?, ?, ?, ?, NOW())');
            $logStmt->execute(['password_reset', 
                              $user['id'], 
                              $_SERVER['REMOTE_ADDR'] ?? 'unknown', 
                              $_SERVER['HTTP_USER_AGENT'] ?? 'unknown']);
        } catch (Exception $e) {
            // Log but continue if security logging fails
            error_log('Failed to log password reset event: ' . $e->getMessage());
        }
        
        respond(true, 'Password has been reset successfully. You can now log in with your new password.');
    } catch (Exception $e) {
        // Roll back on error
        $pdo->rollBack();
        error_log('Password reset error: ' . $e->getMessage());
        respond(false, 'Failed to update password. Please try again later.');
    }
} catch (Exception $e) {
    error_log('Password reset error: ' . $e->getMessage());
    respond(false, 'An error occurred while resetting your password.');
}
