<?php

/**
 * Product Tag Sitemap Provider
 *
 * Generates sitemaps for WooCommerce product tags.
 *
 * @package ProRank\SEO\Modules\Indexing\Sitemaps
 * @since   2.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Modules\Indexing\Sitemaps;

use ProRank\SEO\Core\SettingsManager;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}


/**
 * ProductTagSitemapProvider class
 */


class ProductTagSitemapProvider extends BaseSitemapProvider {
    private ?SettingsManager $settings_manager = null;
    
    /**
     * Provider slug
     *
     * @var string
     */
    protected string $slug = 'product_tag';
    
    /**
     * Provider name
     *
     * @var string
     */
    protected string $name = 'Product Tags';
    
    /**
     * Items per page
     *
     * @var int
     */
    protected int $items_per_page = 1000;
    
    /**
     * Check if provider is enabled
     *
     * @return bool
     */
    public function is_enabled(): bool {
        // Check if WooCommerce is active
        if (!class_exists('WooCommerce')) {
            return false;
        }
        
        // Check settings
        $plugin = \ProRank\SEO\Plugin::get_instance();
        $settings_manager = $this->settings_manager ?: $plugin->settings();
        $sitemap_settings = $this->resolve_sitemap_settings($settings_manager);
        
        // Check if WC integration is enabled
        $wc_enabled = $settings_manager->get('enable_wc_sitemap_integration', 'ecommerce_seo', true);
        if (!$wc_enabled) {
            return false;
        }
        
        // Check if product tags are included
        $enabled_taxonomies = $sitemap_settings['include_taxonomies'] ?? ['category', 'post_tag'];

        return in_array('product_tag', $enabled_taxonomies, true)
            && $settings_manager->get('sitemap_include_product_tags', 'ecommerce_seo', true);
    }
    
    /**
     * Get total pages
     *
     * @return int
     */
    public function get_total_pages(): int {
        $terms = get_terms([
            'taxonomy' => 'product_tag',
            'hide_empty' => true,
            'fields' => 'ids',
        ]);
        
        if (is_wp_error($terms)) {
            return 0;
        }
        
        $total_items = count($terms);
        return (int) ceil($total_items / $this->items_per_page);
    }
    
    /**
     * Generate sitemap
     *
     * @param int $page Page number.
     * @return string XML content.
     */
    public function generate(int $page = 1): string {
        $offset = ($page - 1) * $this->items_per_page;
        
        $terms = get_terms([
            'taxonomy' => 'product_tag',
            'hide_empty' => true,
            'orderby' => 'name',
            'order' => 'ASC',
            'number' => $this->items_per_page,
            'offset' => $offset,
        ]);
        
        if (is_wp_error($terms)) {
            $terms = [];
        }
        
        $xml = new \XMLWriter();
        $xml->openMemory();
        $xml->setIndent(true);
        
        // Start XML document
        $xml->startDocument('1.0', 'UTF-8');
        
        // Add promotional comment
        $xml->writeComment(' Generated by ProRank SEO - https://prorank.io ');
        
        // Start urlset
        $xml->startElement('urlset');
        $xml->writeAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
        
        // Add tags
        foreach ($terms as $term) {
            // Skip if excluded by SEO settings
            $noindex = get_term_meta($term->term_id, '_prorank_seo_noindex', true);
            if ($noindex) {
                continue;
            }
            
            $xml->startElement('url');
            
            // Location
            $term_link = get_term_link($term, 'product_tag');
            if (!is_wp_error($term_link)) {
                $xml->writeElement('loc', $term_link);
            }
            
            // Last modified - use most recent product with this tag
            $lastmod = $this->get_tag_lastmod($term->term_id);
            if ($lastmod) {
                $xml->writeElement('lastmod', $lastmod);
            }
            
            // Change frequency
            $xml->writeElement('changefreq', 'weekly');
            
            // Priority
            $xml->writeElement('priority', '0.5');
            
            $xml->endElement(); // url
        }
        
        $xml->endElement(); // urlset
        $xml->endDocument();
        
        return $xml->outputMemory();
    }

    /**
     * Generate XML content for the requested sitemap page.
     *
     * @param int $page Page number.
     * @return string
     */
    public function generate_xml(int $page = 1): string {
        return $this->generate($page);
    }
    
    /**
     * Get last modified date for tag
     *
     * @param int $term_id Term ID.
     * @return string|null
     */
    private function get_tag_lastmod(int $term_id): ?string {
        // Get most recent product with this tag
        $args = [
            'post_type' => 'product',
            'post_status' => 'publish',
            'posts_per_page' => 1,
            'orderby' => 'modified',
            'order' => 'DESC',
            'tax_query' => [
                [
                    'taxonomy' => 'product_tag',
                    'field' => 'term_id',
                    'terms' => $term_id,
                ],
            ],
            'fields' => 'ids',
        ];
        
        $query = new \WP_Query($args);
        
        if ($query->have_posts()) {
            $post_id = $query->posts[0];
            return get_post_modified_time('c', true, $post_id);
        }
        
        return null;
    }

    /**
     * Get the most recent modification date for the sitemap page.
     *
     * @param int $page Page number.
     * @return string
     */
    protected function get_last_modified(int $page = 1): string {
        $args = [
            'post_type' => 'product',
            'post_status' => 'publish',
            'posts_per_page' => 1,
            'orderby' => 'modified',
            'order' => 'DESC',
            'tax_query' => [
                [
                    'taxonomy' => 'product_tag',
                    'operator' => 'EXISTS',
                ],
            ],
            'fields' => 'ids',
        ];

        $query = new \WP_Query($args);
        if ($query->have_posts()) {
            return (string) get_post_modified_time('c', true, (int) $query->posts[0]);
        }

        return gmdate('c');
    }
    
    /**
     * Get index entries for sitemap index
     *
     * @return array
     */
    public function get_index_entries(): array {
        $entries = [];
        $total_pages = $this->get_total_pages();
        
        for ($page = 1; $page <= $total_pages; $page++) {
            $loc = home_url('product_tag-sitemap' . ($page > 1 ? $page : '') . '.xml');
            
            // Get last modified date from most recent product
            $args = [
                'post_type' => 'product',
                'post_status' => 'publish',
                'posts_per_page' => 1,
                'orderby' => 'modified',
                'order' => 'DESC',
                'tax_query' => [
                    [
                        'taxonomy' => 'product_tag',
                        'operator' => 'EXISTS',
                    ],
                ],
                'fields' => 'ids',
            ];
            
            $query = new \WP_Query($args);
            $lastmod = null;
            
            if ($query->have_posts()) {
                $post_id = $query->posts[0];
                $lastmod = get_post_modified_time('c', true, $post_id);
            }
            
            $entry = ['loc' => $loc];
            if ($lastmod) {
                $entry['lastmod'] = $lastmod;
            }
            
            $entries[] = $entry;
        }
        
        return $entries;
    }
}
