<?php
/**
 * add_pin.php
 * 
 * Admin endpoint to add a withdrawal PIN for a specific user
 * Supports multiple PINs per user and validates against user pin settings
 */

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
$allowed_origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
header("Access-Control-Allow-Origin: $allowed_origin");
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
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;
}

// 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';

// Require admin authentication
requireAdmin(true);

require_once 'config.php';
require_once 'db.php';

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

// Get and validate POST data
$json_data = file_get_contents('php://input');
$data = json_decode($json_data, true);

if (!$data || !isset($data['user_id']) || !isset($data['pin'])) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Missing required fields']);
    exit;
}

$user_id = intval($data['user_id']);
$pin = trim($data['pin']);
$notes = isset($data['notes']) ? trim($data['notes']) : null;

// Validate PIN
if (strlen($pin) < 6 || strlen($pin) > 20 || !preg_match('/^[0-9]+$/', $pin)) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'PIN must be 6-20 digits']);
    exit;
}

try {
    // Begin transaction
    $pdo->beginTransaction();
    
    // Check if user exists
    $userStmt = $pdo->prepare("SELECT id, username, email FROM users WHERE id = ?");
    $userStmt->execute([$user_id]);
    $user = $userStmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$user) {
        throw new Exception('User not found');
    }
    
    // Get user pin settings
    $settingsStmt = $pdo->prepare("
        SELECT * FROM user_pin_settings 
        WHERE user_id = ? 
        LIMIT 1
    ");
    
    $settingsStmt->execute([$user_id]);
    $settings = $settingsStmt->fetch(PDO::FETCH_ASSOC);
    
    // If no settings exist, create default settings
    if (!$settings) {
        $createSettingsStmt = $pdo->prepare("
            INSERT INTO user_pin_settings 
            (user_id, pin_enabled, created_at) 
            VALUES (?, 1, NOW())
        ");
        
        $createSettingsStmt->execute([$user_id]);
        $settings = [
            'id' => $pdo->lastInsertId(),
            'user_id' => $user_id,
            'pin_enabled' => 1,
            'max_pins' => 5,
            'pin_expiry_days' => 30
        ];
    }
    
    // Check if PIN generation is enabled for this user
    if ($settings['pin_enabled'] != 1) {
        throw new Exception('PIN generation is disabled for this user');
    }
    
    // Check if user already has maximum allowed PINs
    $countStmt = $pdo->prepare("
        SELECT COUNT(*) FROM withdrawal_pins 
        WHERE user_id = ? AND status = 'active'
    ");
    
    $countStmt->execute([$user_id]);
    $pinCount = $countStmt->fetchColumn();
    
    if ($pinCount >= $settings['max_pins']) {
        throw new Exception("User already has maximum allowed PINs ({$settings['max_pins']})");
    }
    
    // Insert new PIN
    $insertStmt = $pdo->prepare("
        INSERT INTO withdrawal_pins 
        (user_id, pin, status, created_at) 
        VALUES (?, ?, 'active', NOW())
    ");
    
    $insertStmt->execute([$user_id, $pin]);
    $pin_id = $pdo->lastInsertId();
    
    // Create admin log
    $logStmt = $pdo->prepare("
        INSERT INTO admin_logs 
        (admin_id, action, target_type, target_id, details, created_at) 
        VALUES (?, 'add_withdrawal_pin', 'user', ?, ?, NOW())
    ");
    
    $log_details = json_encode([
        'user_id' => $user_id,
        'pin_id' => $pin_id,
        'notes' => $notes
    ]);
    
    $logStmt->execute([isset($_SESSION['admin_id']) ? $_SESSION['admin_id'] : 1, $user_id, $log_details]);
    
    // Commit the transaction
    $pdo->commit();
    
    // Return success response
    echo json_encode([
        'success' => true,
        'message' => 'Withdrawal PIN added successfully',
        'pin' => [
            'id' => $pin_id,
            'user_id' => $user_id,
            'username' => $user['username'],
            'email' => $user['email'],
            'pin' => $pin, // Only show PIN once for security
            'status' => 'active',
            'created_at' => date('Y-m-d H:i:s')
        ]
    ]);
    
} catch (PDOException $e) {
    // Rollback transaction if in progress
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    
    error_log('Database error adding withdrawal PIN: ' . $e->getMessage());
    
    http_response_code(500);
    echo json_encode([
        'success' => false, 
        'message' => 'Database error adding withdrawal PIN.'
    ]);
    
} catch (Exception $e) {
    // Rollback transaction if in progress
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    
    http_response_code(400);
    echo json_encode([
        'success' => false, 
        'message' => $e->getMessage()
    ]);
}
