<?php
/**
 * Core Functions
 * Traveler - Tour & Travel Web Application
 */

// Start output buffering to prevent "headers already sent" errors
ob_start();

require_once __DIR__ . '/../config/database.php';

// Start session if not already started
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

/**
 * Get a setting value from database
 */
function getSetting($key, $default = '') {
    $db = getDBConnection();
    $stmt = $db->prepare("SELECT setting_value FROM settings WHERE setting_key = ?");
    $stmt->execute([$key]);
    $result = $stmt->fetch();
    return $result ? $result['setting_value'] : $default;
}

/**
 * Update a setting value
 */
function updateSetting($key, $value) {
    $db = getDBConnection();
    $stmt = $db->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = ?");
    return $stmt->execute([$key, $value, $value]);
}

/**
 * Get all settings as associative array
 */
function getAllSettings() {
    $db = getDBConnection();
    $stmt = $db->query("SELECT setting_key, setting_value FROM settings");
    $settings = [];
    while ($row = $stmt->fetch()) {
        // Decode HTML entities to handle previously encoded values
        // This fixes double-encoding issues with ampersands and other special chars
        $settings[$row['setting_key']] = html_entity_decode($row['setting_value'], ENT_QUOTES, 'UTF-8');
    }
    return $settings;
}

/**
 * Sanitize input
 */
function sanitize($input) {
    return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}

/**
 * Generate a unique booking ID
 */
function generateBookingId() {
    $prefix = getSetting('invoice_prefix', 'TRV');
    $year = date('Y');
    $db = getDBConnection();
    $stmt = $db->query("SELECT COUNT(*) as count FROM bookings WHERE YEAR(created_at) = YEAR(CURDATE())");
    $count = $stmt->fetch()['count'] + 1;
    return $prefix . '-' . $year . '-' . str_pad($count, 3, '0', STR_PAD_LEFT);
}

/**
 * Generate a unique transaction ID
 */
function generateTransactionId() {
    return 'TXN-' . date('Y') . '-' . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
}

/**
 * Create URL-friendly slug
 */
function createSlug($string) {
    $slug = strtolower(trim($string));
    $slug = preg_replace('/[^a-z0-9-]/', '-', $slug);
    $slug = preg_replace('/-+/', '-', $slug);
    return trim($slug, '-');
}

/**
 * Upload file
 */
function uploadFile($file, $directory = 'general', $allowedTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp'], $maxSize = 5) {
    $uploadDir = UPLOAD_PATH . $directory . '/';
    
    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0777, true);
    }
    
    $fileName = $file['name'];
    $fileTmp = $file['tmp_name'];
    $fileSize = $file['size'];
    $fileError = $file['error'];
    
    if ($fileError !== UPLOAD_ERR_OK) {
        return ['success' => false, 'message' => 'Upload error occurred'];
    }
    
    $fileExt = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
    
    if (!in_array($fileExt, $allowedTypes)) {
        return ['success' => false, 'message' => 'File type not allowed'];
    }
    
    $maxSizeBytes = $maxSize * 1024 * 1024; // Default 5MB
    if ($fileSize > $maxSizeBytes) {
        return ['success' => false, 'message' => "File size exceeds {$maxSize}MB limit"];
    }
    
    $newFileName = uniqid() . '_' . time() . '.' . $fileExt;
    $destination = $uploadDir . $newFileName;
    
    if (move_uploaded_file($fileTmp, $destination)) {
        return ['success' => true, 'filename' => $newFileName, 'path' => $directory . '/' . $newFileName];
    }
    
    return ['success' => false, 'message' => 'Failed to move uploaded file'];
}

/**
 * Upload video file
 */
function uploadVideo($file) {
    return uploadFile($file, 'videos', ['mp4', 'mov', 'avi', 'webm', 'mkv'], 50); // 50MB limit
}

/**
 * Extract YouTube video ID from URL
 */
function getYouTubeId($url) {
    $pattern = '/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i';
    if (preg_match($pattern, $url, $match)) {
        return $match[1];
    }
    return null;
}

/**
 * Get YouTube thumbnail URL
 */
function getYouTubeThumbnail($videoId, $quality = 'medium') {
    $qualities = ['default' => 'default', 'low' => 'mqdefault', 'medium' => 'hqdefault', 'high' => 'maxresdefault'];
    $quality = $qualities[$quality] ?? 'mqdefault';
    return "https://img.youtube.com/vi/{$videoId}/{$quality}.jpg";
}

/**
 * Get package videos
 */
function getPackageVideos($packageId) {
    $db = getDBConnection();
    $stmt = $db->prepare("SELECT * FROM package_videos WHERE package_id = ? ORDER BY sort_order ASC");
    $stmt->execute([$packageId]);
    return $stmt->fetchAll();
}

/**
 * Delete package image
 */
function deletePackageImage($imageId) {
    $db = getDBConnection();
    $stmt = $db->prepare("SELECT * FROM package_images WHERE id = ?");
    $stmt->execute([$imageId]);
    $image = $stmt->fetch();
    
    if ($image) {
        // Delete file from server
        deleteFile('packages/' . $image['image']);
        // Delete from database
        $db->prepare("DELETE FROM package_images WHERE id = ?")->execute([$imageId]);
        return true;
    }
    return false;
}

/**
 * Delete package video
 */
function deletePackageVideo($videoId) {
    $db = getDBConnection();
    $stmt = $db->prepare("SELECT * FROM package_videos WHERE id = ?");
    $stmt->execute([$videoId]);
    $video = $stmt->fetch();
    
    if ($video) {
        if ($video['video_type'] === 'upload' && $video['video_file']) {
            deleteFile('videos/' . $video['video_file']);
        }
        $db->prepare("DELETE FROM package_videos WHERE id = ?")->execute([$videoId]);
        return true;
    }
    return false;
}

/**
 * Delete uploaded file
 */
function deleteFile($filePath) {
    $fullPath = UPLOAD_PATH . $filePath;
    if (file_exists($fullPath)) {
        return unlink($fullPath);
    }
    return false;
}

/**
 * Format currency
 */
function formatCurrency($amount) {
    $symbol = getSetting('currency_symbol', '₹');
    return $symbol . number_format($amount, 2);
}

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

/**
 * Check if user is logged in
 */
function isLoggedIn() {
    return isset($_SESSION['user_id']);
}

/**
 * Check if user is admin
 */
function isAdmin() {
    return isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin';
}

/**
 * Redirect to URL
 */
function redirect($url) {
    // Clean any output that might have been sent
    if (ob_get_level()) {
        ob_end_clean();
    }
    header("Location: $url");
    exit;
}

/**
 * Set flash message
 */
function setFlash($type, $message) {
    $_SESSION['flash'] = ['type' => $type, 'message' => $message];
}

/**
 * Get and clear flash message
 */
function getFlash() {
    if (isset($_SESSION['flash'])) {
        $flash = $_SESSION['flash'];
        unset($_SESSION['flash']);
        return $flash;
    }
    return null;
}

/**
 * Log activity
 */
function logActivity($userId, $action, $description) {
    $db = getDBConnection();
    $ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
    $stmt = $db->prepare("INSERT INTO activity_log (user_id, action, description, ip_address) VALUES (?, ?, ?, ?)");
    $stmt->execute([$userId, $action, $description, $ip]);
}

/**
 * Get featured places
 */
function getFeaturedPlaces($limit = 6) {
    $db = getDBConnection();
    $stmt = $db->prepare("SELECT * FROM places WHERE is_featured = 1 AND status = 'active' ORDER BY created_at DESC LIMIT ?");
    $stmt->execute([$limit]);
    return $stmt->fetchAll();
}

/**
 * Get featured packages
 */
function getFeaturedPackages($limit = 6) {
    $db = getDBConnection();
    $stmt = $db->prepare("
        SELECT p.*, pl.name as place_name, pl.slug as place_slug,
        (SELECT pi.image FROM package_images pi WHERE pi.package_id = p.id AND pi.is_primary = 1 LIMIT 1) as primary_image
        FROM packages p 
        JOIN places pl ON p.place_id = pl.id 
        WHERE p.is_featured = 1 AND p.status = 'active' AND pl.status = 'active'
        ORDER BY p.created_at DESC LIMIT ?
    ");
    $stmt->execute([$limit]);
    return $stmt->fetchAll();
}

/**
 * Get all active packages
 */
function getActivePackages($limit = 12, $offset = 0) {
    $db = getDBConnection();
    $stmt = $db->prepare("
        SELECT p.*, pl.name as place_name, pl.slug as place_slug,
        (SELECT pi.image FROM package_images pi WHERE pi.package_id = p.id AND pi.is_primary = 1 LIMIT 1) as primary_image
        FROM packages p 
        JOIN places pl ON p.place_id = pl.id 
        WHERE p.status = 'active' AND pl.status = 'active'
        ORDER BY p.is_featured DESC, p.created_at DESC LIMIT ? OFFSET ?
    ");
    $stmt->execute([$limit, $offset]);
    return $stmt->fetchAll();
}

/**
 * Get package by slug
 */
function getPackageBySlug($slug) {
    $db = getDBConnection();
    $stmt = $db->prepare("
        SELECT p.*, pl.name as place_name, pl.slug as place_slug
        FROM packages p 
        JOIN places pl ON p.place_id = pl.id 
        WHERE p.slug = ? AND p.status = 'active'
    ");
    $stmt->execute([$slug]);
    return $stmt->fetch();
}

/**
 * Get package images
 */
function getPackageImages($packageId) {
    $db = getDBConnection();
    $stmt = $db->prepare("SELECT * FROM package_images WHERE package_id = ? ORDER BY sort_order ASC");
    $stmt->execute([$packageId]);
    return $stmt->fetchAll();
}

/**
 * Get package itinerary
 */
function getPackageItinerary($packageId) {
    $db = getDBConnection();
    $stmt = $db->prepare("SELECT * FROM itinerary WHERE package_id = ? ORDER BY day_number ASC");
    $stmt->execute([$packageId]);
    return $stmt->fetchAll();
}

/**
 * Search packages
 */
function searchPackages($query, $limit = 12) {
    $db = getDBConnection();
    $searchTerm = '%' . $query . '%';
    $stmt = $db->prepare("
        SELECT p.*, pl.name as place_name, pl.slug as place_slug,
        (SELECT pi.image FROM package_images pi WHERE pi.package_id = p.id AND pi.is_primary = 1 LIMIT 1) as primary_image
        FROM packages p 
        JOIN places pl ON p.place_id = pl.id 
        WHERE p.status = 'active' AND pl.status = 'active'
        AND (p.title LIKE ? OR p.description LIKE ? OR pl.name LIKE ?)
        ORDER BY p.is_featured DESC, p.created_at DESC LIMIT ?
    ");
    $stmt->execute([$searchTerm, $searchTerm, $searchTerm, $limit]);
    return $stmt->fetchAll();
}

/**
 * Get active sliders
 */
function getActiveSliders() {
    $db = getDBConnection();
    $stmt = $db->query("SELECT * FROM sliders WHERE status = 'active' ORDER BY sort_order ASC");
    return $stmt->fetchAll();
}

/**
 * Get user by ID
 */
function getUserById($id) {
    $db = getDBConnection();
    $stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->execute([$id]);
    return $stmt->fetch();
}

/**
 * Get user bookings
 */
function getUserBookings($userId) {
    $db = getDBConnection();
    $stmt = $db->prepare("
        SELECT b.*, p.title as package_title, p.slug as package_slug,
        (SELECT pi.image FROM package_images pi WHERE pi.package_id = p.id AND pi.is_primary = 1 LIMIT 1) as package_image
        FROM bookings b 
        JOIN packages p ON b.package_id = p.id 
        WHERE b.user_id = ? 
        ORDER BY b.created_at DESC
    ");
    $stmt->execute([$userId]);
    return $stmt->fetchAll();
}

/**
 * Get user transactions
 */
function getUserTransactions($userId) {
    $db = getDBConnection();
    $stmt = $db->prepare("
        SELECT t.*, b.booking_id as booking_code, p.title as package_title
        FROM transactions t 
        JOIN bookings b ON t.booking_id = b.id 
        JOIN packages p ON b.package_id = p.id 
        WHERE t.user_id = ? 
        ORDER BY t.created_at DESC
    ");
    $stmt->execute([$userId]);
    return $stmt->fetchAll();
}

/**
 * Get dashboard stats for admin
 */
function getAdminDashboardStats() {
    $db = getDBConnection();
    
    $stats = [];
    
    // Today's bookings
    $stmt = $db->query("SELECT COUNT(*) as count FROM bookings WHERE DATE(created_at) = CURDATE()");
    $stats['today_bookings'] = $stmt->fetch()['count'];
    
    // Total packages
    $stmt = $db->query("SELECT COUNT(*) as count FROM packages");
    $stats['total_packages'] = $stmt->fetch()['count'];
    
    // Active packages
    $stmt = $db->query("SELECT COUNT(*) as count FROM packages WHERE status = 'active'");
    $stats['active_packages'] = $stmt->fetch()['count'];
    
    // Total bookings
    $stmt = $db->query("SELECT COUNT(*) as count FROM bookings");
    $stats['total_bookings'] = $stmt->fetch()['count'];
    
    // Total revenue
    $stmt = $db->query("SELECT COALESCE(SUM(amount), 0) as total FROM transactions WHERE status = 'success'");
    $stats['total_revenue'] = $stmt->fetch()['total'];
    
    // Total users
    $stmt = $db->query("SELECT COUNT(*) as count FROM users WHERE role = 'user'");
    $stats['total_users'] = $stmt->fetch()['count'];
    
    // Pending bookings
    $stmt = $db->query("SELECT COUNT(*) as count FROM bookings WHERE status = 'pending'");
    $stats['pending_bookings'] = $stmt->fetch()['count'];
    
    // New enquiries
    $stmt = $db->query("SELECT COUNT(*) as count FROM enquiries WHERE status = 'new'");
    $stats['new_enquiries'] = $stmt->fetch()['count'];
    
    // Total places
    $stmt = $db->query("SELECT COUNT(*) as count FROM places");
    $stats['total_places'] = $stmt->fetch()['count'];
    
    return $stats;
}

/**
 * Get recent activities
 */
function getRecentActivities($limit = 10) {
    $db = getDBConnection();
    $stmt = $db->prepare("
        SELECT al.*, u.name as user_name 
        FROM activity_log al 
        LEFT JOIN users u ON al.user_id = u.id 
        ORDER BY al.created_at DESC LIMIT ?
    ");
    $stmt->execute([$limit]);
    return $stmt->fetchAll();
}

/**
 * Get placeholder image URL based on category
 */
function getPlaceholderImage($category = 'travel', $width = 800, $height = 600) {
    $images = [
        'goa' => 'https://images.unsplash.com/photo-1512343879784-a960bf40e7f2?w=' . $width . '&h=' . $height . '&fit=crop',
        'manali' => 'https://images.unsplash.com/photo-1626621341517-bbf3d9990a23?w=' . $width . '&h=' . $height . '&fit=crop',
        'kerala' => 'https://images.unsplash.com/photo-1602216056096-3b40cc0c9944?w=' . $width . '&h=' . $height . '&fit=crop',
        'rajasthan' => 'https://images.unsplash.com/photo-1477587458883-47145ed94245?w=' . $width . '&h=' . $height . '&fit=crop',
        'andaman' => 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=' . $width . '&h=' . $height . '&fit=crop',
        'ladakh' => 'https://images.unsplash.com/photo-1626015365107-aa4ccea1e4a0?w=' . $width . '&h=' . $height . '&fit=crop',
        'shimla' => 'https://images.unsplash.com/photo-1597074866923-dc0589150458?w=' . $width . '&h=' . $height . '&fit=crop',
        'varanasi' => 'https://images.unsplash.com/photo-1561361513-2d000a50f0dc?w=' . $width . '&h=' . $height . '&fit=crop',
        'slider-1' => 'https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1920&h=800&fit=crop',
        'slider-2' => 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=1920&h=800&fit=crop',
        'slider-3' => 'https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=1920&h=800&fit=crop',
        'travel' => 'https://images.unsplash.com/photo-1488646953014-85cb44e25828?w=' . $width . '&h=' . $height . '&fit=crop',
    ];
    
    $category = strtolower($category);
    
    // Check for partial matches
    foreach ($images as $key => $url) {
        if (strpos($category, $key) !== false) {
            return $url;
        }
    }
    
    return $images['travel'];
}

/**
 * Get image URL - returns placeholder if file doesn't exist
 */
function getImageUrl($filename, $directory = 'general') {
    if (empty($filename)) {
        return getPlaceholderImage($directory);
    }
    
    $filePath = UPLOAD_PATH . $directory . '/' . $filename;
    if (file_exists($filePath)) {
        return UPLOAD_URL . $directory . '/' . $filename;
    }
    
    // For profile images, return UI Avatar placeholder
    if ($directory === 'profiles') {
        // Try to extract name from filename or return default
        $name = str_replace(['.png', '.jpg', '.jpeg', '.webp'], '', $filename);
        if ($name === 'default' || $name === '') {
            return 'https://ui-avatars.com/api/?name=U&background=FF6B35&color=fff&size=200';
        }
        return 'https://ui-avatars.com/api/?name=' . urlencode($name) . '&background=FF6B35&color=fff&size=200';
    }
    
    // Return placeholder based on filename
    return getPlaceholderImage($filename);
}

/**
 * Truncate text
 */
function truncateText($text, $length = 150) {
    if (strlen($text) <= $length) return $text;
    return substr($text, 0, $length) . '...';
}

/**
 * Generate JSON-LD Schema Markup for Structured Data
 */
function generateSchemaMarkup() {
    $settings = getAllSettings();
    
    // Check if schema is enabled
    if (empty($settings['schema_enabled']) || $settings['schema_enabled'] !== '1') {
        return '';
    }
    
    $schema = [];
    $schemaType = $settings['schema_type'] ?? 'LocalBusiness';
    
    // Base schema structure
    $schema['@context'] = 'https://schema.org';
    $schema['@type'] = $schemaType;
    
    // Business Name
    if (!empty($settings['schema_name'])) {
        $schema['name'] = $settings['schema_name'];
    }
    
    // Alternate Name
    if (!empty($settings['schema_alt_name'])) {
        $schema['alternateName'] = $settings['schema_alt_name'];
    }
    
    // Description
    if (!empty($settings['schema_description'])) {
        $schema['description'] = $settings['schema_description'];
    }
    
    // Telephone
    if (!empty($settings['schema_telephone'])) {
        $schema['telephone'] = $settings['schema_telephone'];
    }
    
    // Email
    if (!empty($settings['schema_email'])) {
        $schema['email'] = $settings['schema_email'];
    }
    
    // URL
    if (!empty($settings['schema_url'])) {
        $schema['url'] = $settings['schema_url'];
    }
    
    // Logo
    if (!empty($settings['schema_logo'])) {
        $schema['logo'] = getImageUrl($settings['schema_logo'], 'general');
    }
    
    // Image
    if (!empty($settings['schema_image'])) {
        $schema['image'] = getImageUrl($settings['schema_image'], 'general');
    }
    
    // Price Range
    if (!empty($settings['schema_price_range'])) {
        $schema['priceRange'] = $settings['schema_price_range'];
    }
    
    // Address
    $address = [];
    if (!empty($settings['schema_street_address'])) {
        $address['streetAddress'] = $settings['schema_street_address'];
    }
    if (!empty($settings['schema_address_locality'])) {
        $address['addressLocality'] = $settings['schema_address_locality'];
    }
    if (!empty($settings['schema_address_region'])) {
        $address['addressRegion'] = $settings['schema_address_region'];
    }
    if (!empty($settings['schema_postal_code'])) {
        $address['postalCode'] = $settings['schema_postal_code'];
    }
    if (!empty($settings['schema_address_country'])) {
        $address['addressCountry'] = $settings['schema_address_country'];
    }
    if (!empty($address)) {
        $schema['address'] = $address;
    }
    
    // Geographic coordinates
    if (!empty($settings['schema_latitude']) && !empty($settings['schema_longitude'])) {
        $schema['geo'] = [
            '@type' => 'GeoCoordinates',
            'latitude' => $settings['schema_latitude'],
            'longitude' => $settings['schema_longitude']
        ];
    }
    
    // Opening Hours
    if (!empty($settings['schema_opening_hours'])) {
        $hours = [];
        $lines = explode("\n", $settings['schema_opening_hours']);
        foreach ($lines as $line) {
            $line = trim($line);
            if (!empty($line)) {
                $hours[] = $line;
            }
        }
        if (!empty($hours)) {
            $schema['openingHoursSpecification'] = $hours;
        }
    }
    
    // Founder
    if (!empty($settings['schema_founder'])) {
        $schema['founder'] = [
            '@type' => 'Person',
            'name' => $settings['schema_founder']
        ];
    }
    
    // Founding Date
    if (!empty($settings['schema_founding_date'])) {
        $schema['foundingDate'] = $settings['schema_founding_date'];
    }
    
    // Area Served
    if (!empty($settings['schema_area_served'])) {
        $schema['areaServed'] = $settings['schema_area_served'];
    }
    
    // Service Type
    if (!empty($settings['schema_service_type'])) {
        $schema['serviceType'] = $settings['schema_service_type'];
    }
    
    // Social Profiles
    $sameAs = [];
    if (!empty($settings['schema_facebook'])) $sameAs[] = $settings['schema_facebook'];
    if (!empty($settings['schema_twitter'])) $sameAs[] = $settings['schema_twitter'];
    if (!empty($settings['schema_instagram'])) $sameAs[] = $settings['schema_instagram'];
    if (!empty($settings['schema_linkedin'])) $sameAs[] = $settings['schema_linkedin'];
    if (!empty($settings['schema_youtube'])) $sameAs[] = $settings['schema_youtube'];
    if (!empty($settings['schema_pinterest'])) $sameAs[] = $settings['schema_pinterest'];
    
    if (!empty($sameAs)) {
        $schema['sameAs'] = $sameAs;
    }
    
    // Generate JSON-LD
    if (count($schema) > 2) { // More than just @context and @type
        return "\n" . '<script type="application/ld+json">' . "\n" . 
               json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" . 
               '</script>' . "\n";
    }
    
    return '';
}

/**
 * Calculate discount percentage
 */
function calculateDiscount($originalPrice, $offerPrice) {
    if ($originalPrice <= 0 || !$offerPrice) return 0;
    return round((($originalPrice - $offerPrice) / $originalPrice) * 100);
}
