<?php

namespace App\Http\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Models\Page;
use App\Models\BlogPost;
use App\Models\BlogCategory;
use App\Models\GalleryAlbum;
use App\Models\Event;
use App\Models\Download;

/**
 * ITSWEBER CMS – XML Sitemap Generator
 *
 * Generates a sitemap.xml with all published content for search engine indexing.
 */
class SitemapController extends Controller
{
    public function index(Request $request, array $params = []): void
    {
        $baseUrl = $this->getBaseUrl();
        $db      = $this->app->db();

        $urls = [];

        // Homepage – use most recent page update as lastmod
        $homepageMod = '';
        try {
            $row = $db->fetch("SELECT MAX(updated_at) AS latest FROM iw_pages WHERE status = 'published'");
            $homepageMod = $this->formatDate($row['latest'] ?? '');
        } catch (\Exception $e) {}
        $urls[] = ['loc' => $baseUrl . '/', 'lastmod' => $homepageMod, 'priority' => '1.0', 'changefreq' => 'daily'];

        // Published pages (scheduling-aware)
        $pages = Page::published();
        foreach ($pages as $page) {
            if (!empty($page['is_homepage'])) {
                continue; // Already added as /
            }
            $urls[] = [
                'loc'        => $baseUrl . '/' . $page['slug'],
                'lastmod'    => $this->formatDate($page['updated_at'] ?? $page['created_at'] ?? ''),
                'priority'   => '0.8',
                'changefreq' => 'weekly',
            ];
        }

        // Blog listing
        $blogMod = '';
        try {
            $row = $db->fetch("SELECT MAX(updated_at) AS latest FROM iw_blog_posts WHERE status = 'published'");
            $blogMod = $this->formatDate($row['latest'] ?? '');
        } catch (\Exception $e) {}
        $urls[] = ['loc' => $baseUrl . '/blog', 'lastmod' => $blogMod, 'priority' => '0.7', 'changefreq' => 'daily'];

        // Blog posts (scheduling-aware)
        try {
            $posts = $db->fetchAll(
                "SELECT slug, updated_at, published_at, featured_image FROM iw_blog_posts
                 WHERE status = 'published'
                   AND (unpublish_at IS NULL OR unpublish_at > NOW())
                 ORDER BY COALESCE(published_at, created_at) DESC"
            );
            foreach ($posts as $post) {
                $entry = [
                    'loc'        => $baseUrl . '/blog/' . $post['slug'],
                    'lastmod'    => $this->formatDate($post['updated_at'] ?? $post['published_at'] ?? ''),
                    'priority'   => '0.6',
                    'changefreq' => 'monthly',
                ];
                // Image sitemap for featured image
                if (!empty($post['featured_image'])) {
                    $entry['images'] = [['loc' => $baseUrl . '/uploads/' . ltrim($post['featured_image'], '/')]];
                }
                $urls[] = $entry;
            }
        } catch (\Exception $e) {
            // Blog table may not exist
        }

        // Blog categories
        try {
            $categories = BlogCategory::allWithPostCount();
            foreach ($categories as $cat) {
                if (((int) ($cat['post_count'] ?? 0)) > 0) {
                    $urls[] = [
                        'loc'        => $baseUrl . '/blog/category/' . $cat['slug'],
                        'priority'   => '0.5',
                        'changefreq' => 'weekly',
                    ];
                }
            }
        } catch (\Exception $e) {}

        // Gallery listing
        $urls[] = ['loc' => $baseUrl . '/gallery', 'priority' => '0.6', 'changefreq' => 'weekly'];

        // Gallery albums with image-sitemap
        try {
            $albums = GalleryAlbum::visible();
            foreach ($albums as $album) {
                $entry = [
                    'loc'        => $baseUrl . '/gallery/' . $album['slug'],
                    'lastmod'    => $this->formatDate($album['updated_at'] ?? $album['created_at'] ?? ''),
                    'priority'   => '0.5',
                    'changefreq' => 'monthly',
                ];
                // Load album images for image sitemap
                $images = $db->fetchAll(
                    "SELECT filename, title FROM iw_gallery_images
                     WHERE album_id = :album_id ORDER BY sort_order ASC",
                    ['album_id' => (int) $album['id']]
                );
                if (!empty($images)) {
                    $entry['images'] = [];
                    foreach ($images as $img) {
                        $imgEntry = ['loc' => $baseUrl . '/uploads/' . ltrim($img['filename'], '/')];
                        if (!empty($img['title'])) {
                            $imgEntry['title'] = $img['title'];
                        }
                        $entry['images'][] = $imgEntry;
                    }
                }
                $urls[] = $entry;
            }
        } catch (\Exception $e) {
            // Gallery table may not exist
        }

        // Events listing
        $urls[] = ['loc' => $baseUrl . '/events', 'priority' => '0.6', 'changefreq' => 'weekly'];

        // Published events
        try {
            $events = $db->fetchAll(
                "SELECT slug, updated_at FROM iw_events WHERE publish_status = 'published' ORDER BY start_date DESC"
            );
            foreach ($events as $event) {
                $urls[] = [
                    'loc'        => $baseUrl . '/events/' . $event['slug'],
                    'lastmod'    => $this->formatDate($event['updated_at'] ?? ''),
                    'priority'   => '0.5',
                    'changefreq' => 'monthly',
                ];
            }
        } catch (\Exception $e) {
            // Events table may not exist
        }

        // Downloads listing
        $urls[] = ['loc' => $baseUrl . '/download', 'priority' => '0.5', 'changefreq' => 'weekly'];

        // Published downloads
        try {
            $downloads = $db->fetchAll(
                "SELECT slug, updated_at FROM iw_downloads WHERE status = 'published' ORDER BY created_at DESC"
            );
            foreach ($downloads as $dl) {
                $urls[] = [
                    'loc'        => $baseUrl . '/download/' . $dl['slug'],
                    'lastmod'    => $this->formatDate($dl['updated_at'] ?? ''),
                    'priority'   => '0.4',
                    'changefreq' => 'monthly',
                ];
            }
        } catch (\Exception $e) {
            // Downloads table may not exist
        }

        // Detect whether image sitemap namespace is needed
        $hasImages = false;
        foreach ($urls as $u) {
            if (!empty($u['images'])) {
                $hasImages = true;
                break;
            }
        }

        // Build XML
        $xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
        $xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"';
        if ($hasImages) {
            $xml .= "\n        xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\"";
        }
        $xml .= ">\n";

        foreach ($urls as $url) {
            $xml .= "  <url>\n";
            $xml .= "    <loc>" . htmlspecialchars($url['loc'], ENT_XML1, 'UTF-8') . "</loc>\n";
            if (!empty($url['lastmod'])) {
                $xml .= "    <lastmod>" . $url['lastmod'] . "</lastmod>\n";
            }
            if (!empty($url['changefreq'])) {
                $xml .= "    <changefreq>" . $url['changefreq'] . "</changefreq>\n";
            }
            if (!empty($url['priority'])) {
                $xml .= "    <priority>" . $url['priority'] . "</priority>\n";
            }
            if (!empty($url['images'])) {
                foreach ($url['images'] as $img) {
                    $xml .= "    <image:image>\n";
                    $xml .= "      <image:loc>" . htmlspecialchars($img['loc'], ENT_XML1, 'UTF-8') . "</image:loc>\n";
                    if (!empty($img['title'])) {
                        $xml .= "      <image:title>" . htmlspecialchars($img['title'], ENT_XML1, 'UTF-8') . "</image:title>\n";
                    }
                    $xml .= "    </image:image>\n";
                }
            }
            $xml .= "  </url>\n";
        }

        $xml .= "</urlset>\n";

        header('Content-Type: application/xml; charset=UTF-8');
        echo $xml;
        exit;
    }

    private function getBaseUrl(): string
    {
        $base = rtrim(config('base_url', ''), '/');
        if ($base === '') {
            $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
            $host   = $_SERVER['HTTP_HOST'] ?? 'localhost';
            $base   = $scheme . '://' . $host;
        }
        return $base;
    }

    private function formatDate(string $datetime): string
    {
        if (empty($datetime)) {
            return '';
        }
        try {
            return (new \DateTime($datetime))->format('Y-m-d');
        } catch (\Exception $e) {
            return '';
        }
    }
}
