<?php
/**
 * TamRank Content Type Config
 *
 * Helper class for building and reading content type configuration:
 * which post types and taxonomies are enabled for SEO fields, Audit, and Sitemap.
 *
 * @package TamRank
 */

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

class TamRank_Content_Type_Config
{

    /**
     * Build default config based on live publicly_queryable post types and taxonomies.
     *
     * Uses `public => true` query then filters out any type where
     * `publicly_queryable === false` (explicitly set to false). This ensures
     * core types like `post`, `page`, `category`, and `post_tag` — which have
     * `publicly_queryable = null` (inherits from `public`) — are included.
     *
     * @return array {
     *     'general' => [
     *         'taxonomies' => [ 'category' => ['seo_fields' => true, 'audit' => true], ... ],
     *         'post_types' => [ 'post' => ['audit' => true], ... ],
     *     ],
     *     'sitemap' => [
     *         'taxonomies' => [ 'category' => true, ... ],
     *         'post_types' => [ 'post' => true, ... ],
     *     ],
     * }
     */
    public static function build_defaults(): array
    {
        $defaults = [
            'general' => [
                'taxonomies' => [],
                'post_types' => [],
            ],
            'sitemap' => [
                'taxonomies' => [],
                'post_types' => [],
            ],
        ];

        // Post types: public=true, skip attachment and internal-only types.
        // Note: WP core registers 'page' with publicly_queryable=false, but pages
        // ARE public frontend content — so we only skip attachment explicitly.
        $all_post_types = get_post_types(['public' => true], 'objects');
        foreach ($all_post_types as $slug => $pt) {
            if ($slug === 'attachment') {
                continue;
            }
            // Skip types that are explicitly non-queryable, EXCEPT 'page' (WP quirk)
            if ($pt->publicly_queryable === false && $slug !== 'page') {
                continue;
            }
            $defaults['general']['post_types'][$slug] = ['audit' => true];
            $defaults['sitemap']['post_types'][$slug]  = true;
        }

        // Internal taxonomies that should never appear in config/sitemap
        $internal_taxonomies = ['post_format', 'nav_menu', 'link_category', 'wp_theme', 'wp_template_part_area'];

        // Taxonomies: public=true, skip internal ones
        $all_taxonomies = get_taxonomies(['public' => true], 'objects');
        foreach ($all_taxonomies as $slug => $tax) {
            if (in_array($slug, $internal_taxonomies, true)) {
                continue;
            }
            if ($tax->publicly_queryable === false) {
                continue;
            }
            $defaults['general']['taxonomies'][$slug] = [
                'seo_fields' => true,
                'audit'      => true,
            ];
            $defaults['sitemap']['taxonomies'][$slug] = true;
        }

        return $defaults;
    }

    /**
     * Get slugs of post types enabled for audit.
     *
     * Reads general post_types config and returns slugs where audit is truthy.
     *
     * @return array Plain array of slug strings, e.g. ['post', 'page', 'product'].
     *               Returns empty array if none are enabled.
     */
    public static function get_enabled_audit_slugs(): array
    {
        $config = self::get_config();
        $slugs = [];

        if (!isset($config['general']['post_types']) || !is_array($config['general']['post_types'])) {
            // Fallback: no config yet, use post + page
            return array('post', 'page');
        }

        foreach ($config['general']['post_types'] as $slug => $settings) {
            if (!empty($settings['audit'])) {
                $slugs[] = $slug;
            }
        }

        // Safety: always return at least post + page
        if (empty($slugs)) {
            return array('post', 'page');
        }

        return $slugs;
    }

    /**
     * Get slugs of taxonomies enabled for audit.
     *
     * Reads general taxonomies config and returns slugs where audit is truthy.
     *
     * @return array Plain array of slug strings, e.g. ['category', 'post_tag'].
     *               Returns empty array if none are enabled.
     */
    public static function get_enabled_audit_taxonomy_slugs(): array
    {
        $config = self::get_config();
        $slugs = [];

        if (!isset($config['general']['taxonomies']) || !is_array($config['general']['taxonomies'])) {
            return $slugs;
        }

        foreach ($config['general']['taxonomies'] as $slug => $settings) {
            if (!empty($settings['audit'])) {
                $slugs[] = $slug;
            }
        }

        return $slugs;
    }

    /**
     * Get slugs of post types enabled for sitemap.
     *
     * Reads sitemap post_types config and returns slugs where value is truthy.
     *
     * @return array Plain array of slug strings, e.g. ['post', 'page', 'product'].
     *               Returns empty array if none are enabled.
     */
    public static function get_enabled_sitemap_slugs(): array
    {
        $config = self::get_config();
        $slugs = [];

        if (!isset($config['sitemap']['post_types']) || !is_array($config['sitemap']['post_types'])) {
            return $slugs;
        }

        foreach ($config['sitemap']['post_types'] as $slug => $enabled) {
            if (!empty($enabled)) {
                $slugs[] = $slug;
            }
        }

        return $slugs;
    }

    /**
     * Get slugs of taxonomies enabled for sitemap.
     *
     * Reads sitemap taxonomies config and returns slugs where value is truthy.
     *
     * @return array Plain array of slug strings, e.g. ['category', 'post_tag'].
     *               Returns empty array if none are enabled.
     */
    public static function get_enabled_sitemap_taxonomy_slugs(): array
    {
        $config = self::get_config();
        $slugs = [];

        if (!isset($config['sitemap']['taxonomies']) || !is_array($config['sitemap']['taxonomies'])) {
            return $slugs;
        }

        foreach ($config['sitemap']['taxonomies'] as $slug => $enabled) {
            if (!empty($enabled)) {
                $slugs[] = $slug;
            }
        }

        return $slugs;
    }

    /**
     * Get merged config: defaults overlaid with saved values from wp_options.
     *
     * Reads `tam_rank_general_settings[content_types]` and
     * `tam_rank_sitemap_settings[content_types]`, then merges them over
     * the live defaults via array_replace_recursive().
     *
     * @return array Same structure as build_defaults().
     */
    public static function get_config(): array
    {
        $defaults = self::build_defaults();

        // Read saved general content_types
        $general_settings = get_option('tam_rank_general_settings', []);
        $saved_general_ct = isset($general_settings['content_types']) && is_array($general_settings['content_types'])
            ? $general_settings['content_types']
            : [];

        // Read saved sitemap content_types
        $sitemap_settings = get_option('tam_rank_sitemap_settings', []);
        $saved_sitemap_ct = isset($sitemap_settings['content_types']) && is_array($sitemap_settings['content_types'])
            ? $sitemap_settings['content_types']
            : [];

        // Merge saved values over defaults (array_replace_recursive preserves sub-keys)
        $config = [
            'general' => array_replace_recursive($defaults['general'], $saved_general_ct),
            'sitemap' => array_replace_recursive($defaults['sitemap'], $saved_sitemap_ct),
        ];

        return $config;
    }
}

/**
 * Thin alias for tamrank_get_content_type_config().
 * Convenience function for Phase 12 and other callers.
 *
 * @return array Content type config (merged defaults + saved values).
 */
function tamrank_get_content_type_config(): array
{
    return TamRank_Content_Type_Config::get_config();
}
