<?php
declare(strict_types=1);

namespace Celena\Module\Seo;

use Celena\Core\Database\Connection;
use Celena\Core\Http\Request;
use Celena\Core\Http\Response;
use Celena\Core\Security\Auth;
use Celena\Core\Template\Engine;
use Celena\Module\AdminBase\AdminController;
use Celena\Module\Settings\Options;

/**
 * SEO-раздел: обзор настроек, sitemap, robots.txt.
 * Сама генерация sitemap/robots идёт в публичных роутах (см. bootstrap).
 */
final class SeoController extends AdminController
{
    public function __construct(
        Engine $engine,
        Auth $auth,
        Options $options,
        private readonly Connection $conn,
    ) {
        parent::__construct($engine, $auth, $options);
    }

    public function index(Request $request): Response
    {
        $newsTotal = $this->conn->builder('celena_news')->where('status', '=', 'published')->count();
        $pagesTotal = $this->conn->builder('celena_pages')->where('status', '=', 'published')->count();
        return $this->view('admin/seo/index', [
            'counts' => [
                'news' => $newsTotal,
                'pages' => $pagesTotal,
            ],
            'site_url' => (string) $this->options->get('site_url', ''),
        ], 'seo', 'SEO');
    }

    public function sitemap(Request $request): Response
    {
        $url = (string) $this->options->get('site_url', '');
        $items = [];
        foreach ($this->conn->builder('celena_pages')->where('status', '=', 'published')->get() as $p) {
            $items[] = ['loc' => $url . '/p/' . $p['slug'], 'lastmod' => (string) ($p['updated_at'] ?? $p['created_at'])];
        }
        foreach ($this->conn->builder('celena_news')->where('status', '=', 'published')->orderBy('published_at', 'desc')->get() as $n) {
            $items[] = ['loc' => $url . '/news/' . $n['slug'], 'lastmod' => (string) ($n['updated_at'] ?? $n['published_at'])];
        }
        $xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
        $xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
        $xml .= '  <url><loc>' . htmlspecialchars($url . '/', ENT_XML1) . '</loc></url>' . "\n";
        foreach ($items as $it) {
            $xml .= '  <url><loc>' . htmlspecialchars($it['loc'], ENT_XML1) . '</loc>';
            if ($it['lastmod'] !== '') {
                $xml .= '<lastmod>' . substr(str_replace(' ', 'T', $it['lastmod']), 0, 19) . '+00:00</lastmod>';
            }
            $xml .= '</url>' . "\n";
        }
        $xml .= '</urlset>';
        return (new Response($xml, 200, ['Content-Type' => 'application/xml; charset=utf-8']));
    }

    public function robots(Request $request): Response
    {
        $url = (string) $this->options->get('site_url', '');
        $body = "User-agent: *\nDisallow: /admin\nDisallow: /storage\n";
        if ($url !== '') {
            $body .= "Sitemap: " . rtrim($url, '/') . "/sitemap.xml\n";
        }
        return Response::text($body);
    }

    public function rss(Request $request): Response
    {
        $siteName = (string) $this->options->get('site_name', 'Celena CMS');
        $url = (string) $this->options->get('site_url', '');
        $rows = $this->conn->builder('celena_news')
            ->where('status', '=', 'published')
            ->orderBy('published_at', 'desc')
            ->limit(20)->get();
        $xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
        $xml .= '<rss version="2.0"><channel>' . "\n";
        $xml .= '  <title>' . htmlspecialchars($siteName, ENT_XML1) . '</title>' . "\n";
        $xml .= '  <link>' . htmlspecialchars($url, ENT_XML1) . '</link>' . "\n";
        $xml .= '  <description>Feed of ' . htmlspecialchars($siteName, ENT_XML1) . '</description>' . "\n";
        foreach ($rows as $n) {
            $link = $url . '/news/' . $n['slug'];
            $xml .= '  <item>' . "\n";
            $xml .= '    <title>' . htmlspecialchars((string) $n['title'], ENT_XML1) . '</title>' . "\n";
            $xml .= '    <link>' . htmlspecialchars($link, ENT_XML1) . '</link>' . "\n";
            $xml .= '    <guid>' . htmlspecialchars($link, ENT_XML1) . '</guid>' . "\n";
            $xml .= '    <pubDate>' . date(DATE_RSS, strtotime((string) $n['published_at'])) . '</pubDate>' . "\n";
            if (!empty($n['short'])) {
                $xml .= '    <description>' . htmlspecialchars((string) $n['short'], ENT_XML1) . '</description>' . "\n";
            }
            $xml .= '  </item>' . "\n";
        }
        $xml .= '</channel></rss>';
        return (new Response($xml, 200, ['Content-Type' => 'application/rss+xml; charset=utf-8']));
    }
}
