<?php
// Disable error display in production
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(E_ALL);

// Define directory paths
define('ROOT_DIR', dirname(__DIR__));
define('DASHBOARD_DIR', __DIR__);
define('LOGS_DIR', __DIR__ . '/logs');

// Ensure logs directory exists
if (!file_exists(LOGS_DIR)) {
    mkdir(LOGS_DIR, 0755, true);
}

// Basic configuration
define('SESSION_DURATION', 3600); // 1 hour
define('MAX_LOGIN_ATTEMPTS', 5);
define('LOCKOUT_DURATION', 900); // 15 minutes
define('OTP_VALIDITY', 300); // 5 minutes

// Load configuration from JSON file
$config = [];
$configFile = __DIR__ . '/config.json';

if (file_exists($configFile)) {
    $configContent = file_get_contents($configFile);
    if ($configContent !== false) {
        $config = json_decode($configContent, true) ?? [];
    }
}

// Set default values if not in config
$config = array_merge([
    'ipqs_api_key' => '',
    'IPDETECTIVE_API_KEY' => '',
    'telegram_bot_token' => '',
    'telegram_chat_id' => ''
], $config);

// Define constants
define('IPQS_API_KEY', $config['ipqs_api_key']);
define('IPDETECTIVE_API_KEY', $config['IPDETECTIVE_API_KEY']);
define('TELEGRAM_BOT_TOKEN', $config['telegram_bot_token']);
define('TELEGRAM_CHAT_ID', $config['telegram_chat_id']);

// Enhanced Security Functions
class Security {
    private static $telegram = null;
    private static $instance = null;

    private function __construct() {
        // Private constructor to prevent direct instantiation
    }

    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    // Initialize Telegram with correct path
    public static function initTelegram() {
        if (self::$telegram === null) {
            $telegramFile = ROOT_DIR . 'telegram_handler.php';
            if (!file_exists($telegramFile)) {
                error_log("Telegram handler file not found at: " . $telegramFile);
                throw new Exception("Required Telegram handler file not found");
            }
            require_once $telegramFile;
            self::$telegram = new TelegramAuth(TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID);
        }
        return self::$telegram;
    }

    public static function checkAuth() {
        if (!isset($_SESSION['admin_logged_in']) || 
            !$_SESSION['admin_logged_in'] || 
            !isset($_SESSION['last_activity']) || 
            (time() - $_SESSION['last_activity'] > SESSION_DURATION)) {
            
            self::logSecurityEvent('Session expired or invalid');
            self::logout();
            return false;
        }
        $_SESSION['last_activity'] = time();
        return true;
    }

    public static function generateCSRFToken() {
        if (!isset($_SESSION['csrf_token'])) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        }
        return $_SESSION['csrf_token'];
    }

    public static function validateCSRFToken($token) {
        if (!isset($_SESSION['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $token)) {
            self::logSecurityEvent('CSRF validation failed');
            return false;
        }
        return true;
    }

    public static function checkLoginAttempts() {
        $attempts = isset($_SESSION['login_attempts']) ? $_SESSION['login_attempts'] : 0;
        $lastAttempt = isset($_SESSION['last_attempt']) ? $_SESSION['last_attempt'] : 0;

        if ($attempts >= MAX_LOGIN_ATTEMPTS && time() - $lastAttempt < LOCKOUT_DURATION) {
            $timeLeft = LOCKOUT_DURATION - (time() - $lastAttempt);
            return ['locked' => true, 'timeLeft' => $timeLeft];
        }

        return ['locked' => false, 'attempts' => $attempts];
    }

    public static function incrementLoginAttempts() {
        $_SESSION['login_attempts'] = ($_SESSION['login_attempts'] ?? 0) + 1;
        $_SESSION['last_attempt'] = time();
    }

    public static function resetLoginAttempts() {
        unset($_SESSION['login_attempts']);
        unset($_SESSION['last_attempt']);
    }

    public static function generateAndSendOTP() {
        try {
            $telegram = self::initTelegram();
            $otp = $telegram->generateOTP();
            $_SESSION['otp'] = $otp;
            $_SESSION['otp_time'] = time();
            return $telegram->sendOTP($otp);
        } catch (Exception $e) {
            self::logSecurityEvent('OTP generation failed: ' . $e->getMessage());
            return false;
        }
    }

    public static function verifyOTP($inputOTP) {
        if (!isset($_SESSION['otp']) || !isset($_SESSION['otp_time'])) {
            return ['success' => false, 'message' => 'No OTP request found'];
        }

        if (time() - $_SESSION['otp_time'] > OTP_VALIDITY) {
            return ['success' => false, 'message' => 'OTP expired'];
        }

        try {
            $telegram = self::initTelegram();
            return $telegram->verifyOTP($inputOTP, $_SESSION['otp'], $_SESSION['otp_time']);
        } catch (Exception $e) {
            self::logSecurityEvent('OTP verification failed: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Verification failed'];
        }
    }

    public static function logout() {
        session_destroy();
        header('Location: login.php');
        exit();
    }

    public static function logSecurityEvent($event) {
        $logFile = LOGS_DIR . 'security.log';
        $timestamp = date('Y-m-d H:i:s');
        $ip = $_SERVER['REMOTE_ADDR'];
        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
        $message = sprintf(
            "[%s] IP: %s | UA: %s | Event: %s\n",
            $timestamp,
            $ip,
            $userAgent,
            $event
        );
        file_put_contents($logFile, $message, FILE_APPEND);
    }

    public static function sanitizeInput($data) {
        if (is_array($data)) {
            return array_map([self::class, 'sanitizeInput'], $data);
        }
        return htmlspecialchars(trim($data), ENT_QUOTES, 'UTF-8');
    }

    public static function validateIP($ip) {
        return filter_var($ip, FILTER_VALIDATE_IP) !== false;
    }

    public static function checkIPQS($ip) {
        if (empty(IPQS_API_KEY)) {
            return true; // Skip check if no API key
        }

        $url = "https://www.ipqualityscore.com/api/json/ip/" . IPQS_API_KEY . "/" . $ip;
        $response = @file_get_contents($url);
        
        if ($response === false) {
            return true; // Allow if check fails
        }

        $data = json_decode($response, true);
        return !($data['proxy'] ?? false) && !($data['vpn'] ?? false);
    }

    public static function logBotEvent($ip, $reason, $botScore, $location, $userAgent) {
        $logFile = LOGS_DIR . 'bots.txt';
        $timestamp = date('Y-m-d H:i:s');
        $logEntry = json_encode([
            'ip' => $ip,
            'reason' => $reason,
            'timestamp' => $timestamp,
            'unix_timestamp' => time(),
            'user_agent' => $userAgent,
            'bot_score' => $botScore,
            'location' => $location
        ]);
        file_put_contents($logFile, $logEntry . "\n", FILE_APPEND);
    }
}

// Initialize session with secure settings
if (session_status() === PHP_SESSION_NONE) {
    ini_set('session.cookie_httponly', 1);
    ini_set('session.cookie_secure', 1);
    ini_set('session.use_only_cookies', 1);
    ini_set('session.cookie_samesite', 'Strict');
    session_start();
}

// Set default timezone
date_default_timezone_set('Africa/Cairo');
?>