<?php
if (!defined('ABSPATH')) {
    exit;
}

class LLMS_Yoast_Integration {
    private function __construct() {
        add_action('init', array($this, 'add_rewrite_rules'), 1);
        add_action('init', array($this, 'maybe_generate_sitemap'), 999);
        add_filter('wpseo_sitemap_index', array($this, 'add_to_index'));
        add_filter('wpseo_sitemap_llms_content', array($this, 'generate_sitemap'));
        add_action('llms_clear_seo_caches', array($this, 'clear_sitemap_cache'));
        add_filter('query_vars', array($this, 'query_vars'));
        add_filter('llms_generator_get_post_meta_description', array($this, 'get_post_meta_description'), 10,2);
        add_filter('llms_generator_get_site_meta_description', array($this, 'get_site_meta_description'), 10);
    }

    public function get_site_meta_description( $site_description ) {
        if (class_exists('WPSEO_Options')) {
            $yoast_description = YoastSEO()->meta->for_posts_page()->description;
            if($yoast_description) {
                $site_description = $yoast_description;
            }
        }
        return $site_description;
    }

    public function get_post_meta_description( $meta_description, $post ) {
        if (function_exists('YoastSEO') && isset(YoastSEO()->meta, YoastSEO()->meta->for_post($post->ID)->description)) {
            return YoastSEO()->meta->for_post($post->ID)->description;
        }
        return $meta_description;
    }

    public function query_vars( $vars ) {
        $vars[] = 'sitemap';
        return $vars;
    }

    public function add_rewrite_rules() {
        global $wp_rewrite;
        $existing_rules = $wp_rewrite->wp_rewrite_rules();
        if (!isset($existing_rules['^llms-sitemap\.xml$'])) {
            add_rewrite_rule('^llms-sitemap\.xml$', 'index.php?sitemap=llms', 'top');
        }
    }

    public function maybe_generate_sitemap() {
        if(isset($_SERVER['REQUEST_URI'])) {
            $request_uri = wp_parse_url(esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])));
            if (isset($request_uri['path']) && $request_uri['path'] == '/llms-sitemap.xml') {
                status_header(200);
                header('Content-Type: application/xml; charset=utf-8');
                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- generate_sitemap() returns XML with all dynamic values pre-escaped via esc_url / esc_xml.
                echo $this->generate_sitemap();
                exit;
            }
        }
    }

    public function generate_sitemap() {
        $settings = apply_filters('get_llms_generator_settings', []);
        if(isset($settings['llms_allow_indexing']) && $settings['llms_allow_indexing']) {
            $latest_post = get_posts([
                'post_type' => 'llms_txt',
                'posts_per_page' => 1,
                'post_status' => 'publish'
            ]);

            if (empty($latest_post) && !class_exists('WPSEO_Sitemaps_Renderer')) {
                return '';
            }

            $url = array(
                'loc' => home_url('/llms.txt'),
                'lastmod' => get_post_modified_time('c', true, $latest_post[0]),
                'changefreq' => 'weekly',
                'priority' => '0.8'
            );

            $loc = esc_url($url['loc']);
            $lastmod = esc_xml($url['lastmod']);
            $changefreq = esc_xml($url['changefreq']);
            $priority = esc_xml($url['priority']);


            $sitemap = sprintf(
                '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">' . "\n" .
                '    <url>' . "\n" .
                '        <loc>%1$s</loc>' . "\n" .
                '        <lastmod>%2$s</lastmod>' . "\n" .
                '        <changefreq>%3$s</changefreq>' . "\n" .
                '        <priority>%4$s</priority>' . "\n" .
                '    </url>' . "\n" .
                '</urlset>',
                $loc,
                $lastmod,
                $changefreq,
                $priority
            );
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Yoast sitemap renderer emits pre-escaped XML.
            echo (new WPSEO_Sitemaps_Renderer())->get_output( $sitemap );
        }
    }

    public function add_to_index($sitemap) {
        $settings = apply_filters('get_llms_generator_settings', []);
        if(isset($settings['llms_allow_indexing']) && $settings['llms_allow_indexing']) {
            $latest_post = get_posts([
                'post_type' => 'llms_txt',
                'posts_per_page' => 1,
                'post_status' => 'publish'
            ]);

            if (!empty($latest_post)) {
                $entry = "\n<sitemap>";
                $entry .= "\n\t<loc>" . esc_url(home_url('llms-sitemap.xml')) . "</loc>";
                $entry .= "\n\t<lastmod>" . esc_xml(get_post_modified_time('c', true, $latest_post[0])) . "</lastmod>";
                $entry .= "\n</sitemap>\n";
                return $sitemap . $entry;
            }
        }

        return $sitemap;
    }

    public function clear_sitemap_cache() {
        do_action('wpseo_cache_clear_sitemap');
    }

    public static function get_instance() {
        static $instance = null;
        if (null === $instance) {
            $instance = new self();
        }
        return $instance;
    }
}

LLMS_Yoast_Integration::get_instance();