<?php
/**
 * IBVTE Management System - Global Configuration
 * All global variables and constants
 */

// Prevent direct access
if (!defined('IBVTE_ACCESS')) {
    define('IBVTE_ACCESS', true);
}

// ============================================
// ENVIRONMENT SETTINGS
// ============================================
$serverHost = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? '';
$isLocalhost = php_sapi_name() === 'cli' || in_array($serverHost, ['localhost', '127.0.0.1']);

if ($isLocalhost) {
    define('ENVIRONMENT', 'development'); // development | production | testing
} else {
    define('ENVIRONMENT', 'production');
}

// Error Reporting
if (ENVIRONMENT === 'development') {
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
} else {
    error_reporting(0);
    ini_set('display_errors', 0);
}

// ============================================
// DATABASE CONFIGURATION
// ============================================
if ($isLocalhost) {
    // LOCAL XAMPP SETTINGS
    define('DB_HOST', '127.0.0.1');
    define('DB_USERNAME', 'root');
    define('DB_PASSWORD', ''); // XAMPP default empty password
    define('DB_NAME', 'ibvte');
} else {
    // LIVE CPANEL SETTINGS
    define('DB_HOST', 'localhost');
    define('DB_USERNAME', 'flightbo_ibvte');
    define('DB_PASSWORD', 'flightbo_ibvte2'); 
    define('DB_NAME', 'flightbo_ibvte');
}

define('DB_CHARSET', 'utf8mb4');
define('DB_PORT', '3306');

// ============================================
// APPLICATION SETTINGS
// ============================================
define('APP_NAME', 'Indian Board of Vocational and Technical Education');
define('APP_SHORT_NAME', 'IBVTE');
define('APP_VERSION', '1.0.0');

// Dynamic URL detection
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)) ? "https://" : "http://";
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';

if ($isLocalhost) {
    define('APP_URL', 'http://localhost/ibvte/');
    define('BASE_URL', '/ibvte/');
} else {
    // On production, detect if we are in a subdirectory or root
    // Most likely the user uploaded to root, so BASE_URL should be /
    // But we'll check if 'ibvte' is part of the path to be safe
    $scriptPath = $_SERVER['SCRIPT_NAME'] ?? '';
    if (strpos($scriptPath, '/ibvte/') === 0) {
        define('BASE_URL', '/ibvte/');
    } else {
        define('BASE_URL', '/');
    }
    define('APP_URL', $protocol . $host . BASE_URL);
}

// Timezone
date_default_timezone_set('Asia/Kolkata');
define('TIMEZONE', 'Asia/Kolkata');

// ============================================
// PATH CONSTANTS
// ============================================
define('ROOT_PATH', __DIR__ . '/');
define('INCLUDES_PATH', ROOT_PATH . 'includes/');
define('ADMIN_PATH', ROOT_PATH . 'admin/');
define('COLLEGE_PATH', ROOT_PATH . 'college/');
define('STUDENT_PATH', ROOT_PATH . 'student/');
define('ARC_PATH', ROOT_PATH . 'arc/');
define('ASSETS_PATH', ROOT_PATH . 'assets/');
define('UPLOADS_PATH', ASSETS_PATH . 'uploads/');
define('PDF_GENERATED_PATH', ROOT_PATH . 'pdf_generated/');

// ============================================
// SECURITY SETTINGS
// ============================================
define('SESSION_NAME', 'IBVTE_SESSION');
define('SESSION_LIFETIME', 1800); // 30 minutes
define('SESSION_SECURE', false); // Set true in production with HTTPS
define('SESSION_HTTP_ONLY', true);

define('MAX_LOGIN_ATTEMPTS', 5);
define('LOCKOUT_DURATION', 900); // 15 minutes
define('PASSWORD_MIN_LENGTH', 8);

define('OTP_LENGTH', 6);
define('OTP_EXPIRY_MINUTES', 10);
define('OTP_MAX_ATTEMPTS', 3);

define('CSRF_TOKEN_NAME', 'csrf_token');
define('CSRF_TOKEN_TIME', 'csrf_token_time');
define('CSRF_TOKEN_LIFETIME', 3600); // 1 hour

// Encryption Keys (Change in production!)
define('ENCRYPTION_KEY', 'ibvte_secret_key_2026_change_in_production');
define('HASH_COST', 10);

// ============================================
// FILE UPLOAD SETTINGS
// ============================================
define('MAX_UPLOAD_SIZE', 5 * 1024 * 1024); // 5MB
define('ALLOWED_IMAGE_TYPES', ['image/jpeg', 'image/png', 'image/gif', 'image/webp']);
define('ALLOWED_DOC_TYPES', [
    'application/pdf',
    'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'image/jpeg',
    'image/png'
]);

// ============================================
// EMAIL SETTINGS (SMTP)
// ============================================
define('SMTP_HOST', 'smtp.gmail.com');
define('SMTP_PORT', 587);
define('SMTP_USERNAME', 'Ibvtedelhi@gmail.com');
define('SMTP_PASSWORD', ''); // App-specific password
define('SMTP_FROM_EMAIL', 'Ibvtedelhi@gmail.com');
define('SMTP_FROM_NAME', 'IBVTE Official');
define('SMTP_ENCRYPTION', 'tls');

// ============================================
// SMS SETTINGS (Twilio or similar)
// ============================================
define('SMS_ENABLED', false);
define('SMS_API_KEY', '');
define('SMS_API_SECRET', '');
define('SMS_FROM_NUMBER', '+91-9627769817');
define('SMS_PROVIDER', 'twilio'); // twilio | msg91 | exotel

// ============================================
// FINANCIAL SETTINGS
// ============================================
define('DEFAULT_CURRENCY', 'INR');
if (!defined('CURRENCY_SYMBOL')) define('CURRENCY_SYMBOL', '₹');
define('MIN_WALLET_BALANCE', 10000); // Minimum balance for colleges
define('ADMISSION_FEE_RETENTION_PCT', 20); // IBVTE retains 20% of admission fee
define('MAX_FUND_REQUEST_AMOUNT', 500000); // Maximum single fund request (5 Lakh)

// ============================================
// INSTITUTION INFO
// ============================================
define('INSTITUTION_NAME', 'Indian Board of Vocational and Technical Education');
define('INSTITUTION_SHORT', 'IBVTE');
define('INSTITUTION_ADDRESS', '60 Futa Road, Samar Garden Colony, Meerut (UP) – 250002');
define('INSTITUTION_PHONE', '+91-9627769817, +91-8057728847');
define('INSTITUTION_EMAIL', 'Ibvtedelhi@gmail.com');
define('INSTITUTION_WEBSITE', 'https://www.ibvte.org');

// ============================================
// RESULT SETTINGS
// ============================================
define('PASS_PERCENTAGE', 40);
define('FIRST_DIVISION_PERCENTAGE', 60);
define('DISTINCTION_PERCENTAGE', 75);
define('MAX_MARKS_DEFAULT', 100);

// Division Constants
function getDivision($percentage) {
    if ($percentage >= 75) return 'distinction';
    if ($percentage >= 60) return 'first';
    if ($percentage >= 50) return 'second';
    if ($percentage >= 40) return 'third';
    return 'fail';
}

function getDivisionLabel($division) {
    $labels = [
        'distinction' => 'Distinction',
        'first' => 'First Division',
        'second' => 'Second Division',
        'third' => 'Third Division',
        'fail' => 'Fail'
    ];
    return $labels[$division] ?? 'Unknown';
}

// ============================================
// ROLE CONSTANTS
// ============================================
define('ROLE_SUPER_ADMIN', 1);
define('ROLE_ADMIN', 2);
define('ROLE_COLLEGE', 3);
define('ROLE_ARC_CENTER', 4);
define('ROLE_STUDENT', 5);

// ============================================
// STATUS CONSTANTS
// ============================================
// Fund Request Status
function getFundRequestStatuses() {
    return [
        'pending' => ['label' => 'Pending', 'class' => 'warning'],
        'under_review' => ['label' => 'Under Review', 'class' => 'info'],
        'approved' => ['label' => 'Approved', 'class' => 'success'],
        'rejected' => ['label' => 'Rejected', 'class' => 'danger'],
        'cancelled' => ['label' => 'Cancelled', 'class' => 'secondary']
    ];
}

// Affiliation Status
function getAffiliationStatuses() {
    return [
        'draft' => ['label' => 'Draft', 'class' => 'secondary'],
        'submitted' => ['label' => 'Submitted', 'class' => 'info'],
        'under_review' => ['label' => 'Under Review', 'class' => 'warning'],
        'inspection_scheduled' => ['label' => 'Inspection Scheduled', 'class' => 'primary'],
        'approved' => ['label' => 'Approved', 'class' => 'success'],
        'rejected' => ['label' => 'Rejected', 'class' => 'danger'],
        'suspended' => ['label' => 'Suspended', 'class' => 'dark']
    ];
}

// Student Status
function getStudentStatuses() {
    return [
        'active' => ['label' => 'Active', 'class' => 'success'],
        'inactive' => ['label' => 'Inactive', 'class' => 'warning'],
        'passed' => ['label' => 'Passed', 'class' => 'primary'],
        'failed' => ['label' => 'Failed', 'class' => 'danger'],
        'dropout' => ['label' => 'Dropout', 'class' => 'secondary'],
        'transferred' => ['label' => 'Transferred', 'class' => 'info']
    ];
}

// ============================================
// UTILITY FUNCTIONS
// ============================================

/**
 * Generate unique ID with prefix
 */
function generateUniqueId($prefix, $length = 8) {
    $timestamp = date('YmdHis');
    $random = strtoupper(substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, $length));
    return $prefix . $timestamp . $random;
}

/**
 * Format currency
 */
function formatCurrency($amount, $withSymbol = true) {
    $formatted = number_format($amount, 2);
    return $withSymbol ? CURRENCY_SYMBOL . ' ' . $formatted : $formatted;
}

/**
 * Format date for display
 */
function formatDate($date, $format = 'd M Y') {
    if (empty($date)) return '-';
    return date($format, strtotime($date));
}

/**
 * Format datetime for display
 */
function formatDateTime($datetime, $format = 'd M Y, h:i A') {
    if (empty($datetime)) return '-';
    return date($format, strtotime($datetime));
}

/**
 * Clean input data
 */
function cleanInput($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
    return $data;
}

/**
 * Generate random string
 */
function generateRandomString($length = 10) {
    return substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length / strlen($x)))), 1, $length);
}

/**
 * Mask sensitive data
 */
function maskData($data, $visibleStart = 2, $visibleEnd = 2) {
    $length = strlen($data);
    if ($length <= $visibleStart + $visibleEnd) {
        return $data;
    }
    return substr($data, 0, $visibleStart) . str_repeat('*', $length - $visibleStart - $visibleEnd) . substr($data, -$visibleEnd);
}

/**
 * Send JSON response
 */
function jsonResponse($success, $message = '', $data = null, $httpCode = 200) {
    http_response_code($httpCode);
    header('Content-Type: application/json');
    echo json_encode([
        'success' => $success,
        'message' => $message,
        'data' => $data,
        'timestamp' => date('Y-m-d H:i:s')
    ]);
    exit;
}

/**
 * Log application errors
 */
function logError($message, $context = []) {
    $logFile = ROOT_PATH . 'logs/error_' . date('Y-m-d') . '.log';
    $logDir = dirname($logFile);
    
    // Try to create directory if it doesn't exist
    if (!is_dir($logDir)) {
        @mkdir($logDir, 0755, true);
    }
    
    // Only log if directory exists and is writable
    if (!is_dir($logDir) || !is_writable($logDir)) {
        // Silently fail - can't log if we can't write
        return;
    }
    
    $logEntry = [
        'timestamp' => date('Y-m-d H:i:s'),
        'message' => $message,
        'context' => $context,
        'ip' => $_SERVER['REMOTE_ADDR'] ?? 'CLI',
        'url' => $_SERVER['REQUEST_URI'] ?? 'CLI'
    ];
    
    @file_put_contents($logFile, json_encode($logEntry) . PHP_EOL, FILE_APPEND | LOCK_EX);
}

/**
 * Get client IP address
 */
function getClientIP() {
    $ipKeys = ['HTTP_CF_CONNECTING_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'];
    foreach ($ipKeys as $key) {
        if (!empty($_SERVER[$key])) {
            return $_SERVER[$key];
        }
    }
    return '0.0.0.0';
}

/**
 * Check if request is AJAX
 */
function isAjaxRequest() {
    return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && 
           strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
}

/**
 * Redirect with message
 */
function redirectWithMessage($url, $message = '', $type = 'info') {
    if (!empty($message)) {
        $_SESSION['flash_message'] = $message;
        $_SESSION['flash_type'] = $type;
    }
    header("Location: $url");
    exit;
}

/**
 * Get flash message
 */
function getFlashMessage() {
    if (!empty($_SESSION['flash_message'])) {
        $message = $_SESSION['flash_message'];
        $type = $_SESSION['flash_type'] ?? 'info';
        unset($_SESSION['flash_message'], $_SESSION['flash_type']);
        return ['message' => $message, 'type' => $type];
    }
    return null;
}

/**
 * Validate Indian mobile number
 */
function isValidIndianMobile($mobile) {
    return preg_match('/^[6-9]\d{9}$/', $mobile);
}

/**
 * Validate email
 */
function isValidEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

/**
 * Generate PDF filename
 */
function generatePdfFilename($type, $id) {
    $timestamp = date('Ymd_His');
    return $type . '_' . $id . '_' . $timestamp . '.pdf';
}

// ============================================
// SESSION INITIALIZATION
// ============================================
if (session_status() === PHP_SESSION_NONE) {
    ini_set('session.name', SESSION_NAME);
    ini_set('session.cookie_lifetime', SESSION_LIFETIME);
    ini_set('session.gc_maxlifetime', SESSION_LIFETIME);
    ini_set('session.cookie_secure', SESSION_SECURE ? 1 : 0);
    ini_set('session.cookie_httponly', SESSION_HTTP_ONLY ? 1 : 0);
    ini_set('session.cookie_samesite', 'Lax');
    session_start();
}

// ============================================
// DATABASE CONNECTION HELPER
// ============================================
function getDB() {
    static $pdo = null;
    
    if ($pdo === null) {
        try {
            $dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET . ";port=" . DB_PORT;
            $pdo = new PDO($dsn, DB_USERNAME, DB_PASSWORD, [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
            ]);
        } catch (PDOException $e) {
            $errorMessage = $e->getMessage();
            if (strpos($errorMessage, 'Unknown database') !== false || strpos($errorMessage, '1049') !== false) {
                try {
                    $dsnNoDb = "mysql:host=" . DB_HOST . ";charset=" . DB_CHARSET . ";port=" . DB_PORT;
                    $tempPdo = new PDO($dsnNoDb, DB_USERNAME, DB_PASSWORD, [
                        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                        PDO::ATTR_EMULATE_PREPARES => false,
                    ]);
                    $tempPdo->exec("CREATE DATABASE IF NOT EXISTS `" . DB_NAME . "` CHARACTER SET " . DB_CHARSET . " COLLATE utf8mb4_unicode_ci");
                    $pdo = new PDO($dsn, DB_USERNAME, DB_PASSWORD, [
                        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                        PDO::ATTR_EMULATE_PREPARES => false,
                    ]);
                } catch (PDOException $inner) {
                    logError('Database setup failed', ['error' => $inner->getMessage()]);
                    if (ENVIRONMENT === 'development') {
                        die('Database setup failed: ' . $inner->getMessage());
                    }
                    die("<div style='padding:20px; font-family:sans-serif; text-align:center;'>
                    <h3 style='color:red;'>Database Setup Failed!</h3>
                    <p>Please check your database credentials and privileges.</p>
                    <p><b>Exact Error:</b> " . htmlspecialchars($inner->getMessage()) . "</p>
                    </div>");
                }
            } else {
                if (ENVIRONMENT === 'development') {
                    logError('Database connection failed', ['error' => $errorMessage]);
                    die('Database connection failed: ' . $errorMessage);
                } else {
                    die("<div style='padding:20px; font-family:sans-serif; text-align:center;'>
                    <h3 style='color:red;'>Database Connection Failed!</h3>
                    <p>Ensure that the user <b>" . DB_USERNAME . "</b> is added to the database <b>" . DB_NAME . "</b> with ALL PRIVILEGES in your cPanel.</p>
                    <p><b>Exact Error:</b> " . htmlspecialchars($errorMessage) . "</p>
                    </div>");
                }
            }
        }
    }
    
    return $pdo;
}

// ============================================
// SET DEFAULT TIMEZONE FOR DATABASE
// ============================================
try {
    $db = getDB();
    $db->exec("SET time_zone = '+05:30'");
} catch (Exception $e) {
    logError('Failed to set timezone', ['error' => $e->getMessage()]);
}
