<?php
// ===================================================================
//      COMPLETE SITEMAP GENERATOR WITH PROPER XML OUTPUT
// ===================================================================

// Disable error reporting for XML output
error_reporting(0);
ini_set('display_errors', 0);

// Suppress output when running via cron
$is_cron = (php_sapi_name() === 'cli');

// Include your database configuration
require_once __DIR__ . '/includes/config.php';

// --- CONFIGURATION ---
define('SITE_URL', 'https://epustakalaya.com'); 
define('SITEMAP_PATH', __DIR__ . '/sitemap.xml');
define('BACKUP_PATH', __DIR__ . '/sitemap_backup.xml');
define('LOG_PATH', __DIR__ . '/logs/sitemap_generator.log');

// Create logs directory if it doesn't exist
if (!is_dir(dirname(LOG_PATH))) {
    @mkdir(dirname(LOG_PATH), 0755, true);
}

// --- LOGGING FUNCTION (only to file, not output) ---
function log_message($message, $type = 'INFO') {
    $timestamp = date('Y-m-d H:i:s');
    $log_entry = "[$timestamp] [$type] $message" . PHP_EOL;
    @file_put_contents(LOG_PATH, $log_entry, FILE_APPEND);
}

/**
 * Adds a URL entry to the XML string
 */
function add_url(&$xml, $loc, $lastmod, $changefreq, $priority) {
    $xml .= '  <url>' . PHP_EOL;
    $xml .= '    <loc>' . htmlspecialchars($loc) . '</loc>' . PHP_EOL;
    $xml .= '    <lastmod>' . htmlspecialchars($lastmod) . '</lastmod>' . PHP_EOL;
    $xml .= '    <changefreq>' . htmlspecialchars($changefreq) . '</changefreq>' . PHP_EOL;
    $xml .= '    <priority>' . htmlspecialchars($priority) . '</priority>' . PHP_EOL;
    $xml .= '  </url>' . PHP_EOL;
}

/**
 * Check if column exists in table
 */
function column_exists($pdo, $table, $column) {
    try {
        $stmt = $pdo->prepare("SHOW COLUMNS FROM `$table` LIKE :column");
        $stmt->execute([':column' => $column]);
        return $stmt->rowCount() > 0;
    } catch (Exception $e) {
        return false;
    }
}

// If accessed directly via browser, output XML header
if (!$is_cron && !isset($_SERVER['HTTP_USER_AGENT'])) {
    header('Content-Type: application/xml; charset=utf-8');
}

try {
    log_message("=========================================");
    log_message("Starting sitemap generation...");
    
    // --- 1. INITIALIZE ---
    $pdo = get_pdo();
    $today = date('Y-m-d');
    $total_urls = 0;
    $start_time = microtime(true);

    // Check which date columns exist
    $books_has_updated = column_exists($pdo, 'books', 'updated_at');
    $books_has_created = column_exists($pdo, 'books', 'created_at');
    
    // Start the XML output
    $xml_content = '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL;
    $xml_content .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . PHP_EOL;

    // --- 2. ADD STATIC PAGES ---
    log_message("Adding static pages...");
    
    $static_pages = [
        ['url' => '/', 'priority' => 1.0, 'changefreq' => 'daily'],
        ['url' => '/categories.php', 'priority' => 0.8, 'changefreq' => 'weekly'],
        ['url' => '/index.php', 'priority' => 0.9, 'changefreq' => 'daily'],
    ];
    
    foreach ($static_pages as $page) {
        add_url($xml_content, SITE_URL . $page['url'], $today, $page['changefreq'], $page['priority']);
        $total_urls++;
    }
    log_message("Added " . count($static_pages) . " static page URLs");

    // --- 3. ADD CATEGORY PAGES ---
    log_message("Fetching categories...");
    
    $category_query = "SELECT slug, name FROM categories WHERE is_hidden = 0 OR is_hidden IS NULL ORDER BY name";
    $stmt = $pdo->query($category_query);
    $categories = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $category_count = count($categories);

    if ($category_count > 0) {
        foreach ($categories as $category) {
            $loc = SITE_URL . '/category.php?slug=' . $category['slug'];
            add_url($xml_content, $loc, $today, 'weekly', 0.7);
            $total_urls++;
        }
        log_message("Added $category_count category URLs");
    } else {
        log_message("No categories found", "WARNING");
    }

    // --- 4. ADD BOOK PAGES ---
    log_message("Fetching books...");
    
    // Build query based on available columns
    $book_query = "SELECT slug, title";
    if ($books_has_updated) {
        $book_query .= ", updated_at";
    } elseif ($books_has_created) {
        $book_query .= ", created_at";
    }
    $book_query .= " FROM books WHERE is_hidden = 0 OR is_hidden IS NULL ORDER BY id DESC";
    $book_query .= " LIMIT 50000";
    
    $stmt = $pdo->query($book_query);
    $books = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $book_count = count($books);

    if ($book_count > 0) {
        foreach ($books as $book) {
            $loc = SITE_URL . '/book.php?slug=' . $book['slug'];
            
            // Determine last modification date
            if ($books_has_updated && !empty($book['updated_at'])) {
                $lastmod = date('Y-m-d', strtotime($book['updated_at']));
            } elseif ($books_has_created && !empty($book['created_at'])) {
                $lastmod = date('Y-m-d', strtotime($book['created_at']));
            } else {
                $lastmod = $today;
            }
            
            add_url($xml_content, $loc, $lastmod, 'monthly', 0.6);
            $total_urls++;
        }
        log_message("Added $book_count book URLs");
    } else {
        log_message("No books found", "WARNING");
    }

    // --- 5. ADD AUTHOR PAGES (if authors table exists) ---
    try {
        $stmt = $pdo->query("SHOW TABLES LIKE 'authors'");
        if ($stmt->rowCount() > 0) {
            log_message("Fetching authors...");
            $author_query = "SELECT slug, name FROM authors WHERE is_hidden = 0 OR is_hidden IS NULL ORDER BY name LIMIT 10000";
            $stmt = $pdo->query($author_query);
            $authors = $stmt->fetchAll(PDO::FETCH_ASSOC);
            $author_count = count($authors);
            
            if ($author_count > 0) {
                foreach ($authors as $author) {
                    $loc = SITE_URL . '/author.php?slug=' . $author['slug'];
                    add_url($xml_content, $loc, $today, 'weekly', 0.5);
                    $total_urls++;
                }
                log_message("Added $author_count author URLs");
            }
        }
    } catch (Exception $e) {
        log_message("Authors table check failed: " . $e->getMessage(), "WARNING");
    }

    // --- 6. ADD PUBLISHER PAGES (if publishers table exists) ---
    try {
        $stmt = $pdo->query("SHOW TABLES LIKE 'publishers'");
        if ($stmt->rowCount() > 0) {
            log_message("Fetching publishers...");
            $publisher_query = "SELECT slug, name FROM publishers WHERE is_hidden = 0 OR is_hidden IS NULL ORDER BY name LIMIT 10000";
            $stmt = $pdo->query($publisher_query);
            $publishers = $stmt->fetchAll(PDO::FETCH_ASSOC);
            $publisher_count = count($publishers);
            
            if ($publisher_count > 0) {
                foreach ($publishers as $publisher) {
                    $loc = SITE_URL . '/publisher.php?slug=' . $publisher['slug'];
                    add_url($xml_content, $loc, $today, 'weekly', 0.5);
                    $total_urls++;
                }
                log_message("Added $publisher_count publisher URLs");
            }
        }
    } catch (Exception $e) {
        log_message("Publishers table check failed: " . $e->getMessage(), "WARNING");
    }

    // --- 7. FINALIZE AND SAVE THE FILE ---
    $xml_content .= '</urlset>';
    
    // Validate XML before saving
    $dom = new DOMDocument();
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    
    // Suppress warnings for invalid XML
    $old_libxml_errors = libxml_use_internal_errors(true);
    
    if ($dom->loadXML($xml_content)) {
        libxml_use_internal_errors($old_libxml_errors);
        
        // Format the XML nicely
        $formatted_xml = $dom->saveXML();
        
        // Save the sitemap file
        if (file_put_contents(SITEMAP_PATH, $formatted_xml)) {
            // Set proper permissions
            @chmod(SITEMAP_PATH, 0644);
            
            $end_time = microtime(true);
            $execution_time = round($end_time - $start_time, 2);
            $file_size = filesize(SITEMAP_PATH);
            
            log_message("✅ Sitemap generated successfully!", "SUCCESS");
            log_message("📊 Total URLs: $total_urls");
            log_message("⏱️ Execution time: {$execution_time} seconds");
            log_message("📦 File size: " . format_file_size($file_size));
            
            // If accessed via browser, output the XML directly
            if (!$is_cron && php_sapi_name() !== 'cli') {
                header('Content-Type: application/xml; charset=utf-8');
                echo $formatted_xml;
                exit;
            }
            
        } else {
            throw new Exception("Failed to write to sitemap.xml");
        }
    } else {
        $errors = libxml_get_errors();
        libxml_use_internal_errors($old_libxml_errors);
        throw new Exception("Invalid XML: " . print_r($errors, true));
    }

} catch (Exception $e) {
    log_message("ERROR: " . $e->getMessage(), "ERROR");
    
    // If accessed via browser, show error as XML
    if (!$is_cron && php_sapi_name() !== 'cli') {
        header('Content-Type: application/xml; charset=utf-8');
        echo '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL;
        echo '<error>' . PHP_EOL;
        echo '  <message>' . htmlspecialchars($e->getMessage()) . '</message>' . PHP_EOL;
        echo '</error>';
    }
    exit(1);
}

/**
 * Format file size for display
 */
function format_file_size($bytes) {
    if ($bytes >= 1073741824) {
        return number_format($bytes / 1073741824, 2) . ' GB';
    } elseif ($bytes >= 1048576) {
        return number_format($bytes / 1048576, 2) . ' MB';
    } elseif ($bytes >= 1024) {
        return number_format($bytes / 1024, 2) . ' KB';
    } else {
        return $bytes . ' bytes';
    }
}
?>