<?php
/**
 * Orientation data gateway for Bricks option and post counts.
 *
 * @package LolaCoreForBricks
 */

declare(strict_types=1);

namespace LolaCoreForBricks\Gateways;

use LolaCoreForBricks\BricksEnv;
use LolaCoreForBricks\Index\IndexReader;
use LolaCoreForBricks\Support\DesignConventionStore;
use LolaCoreForBricks\Support\ExternalFrameworkDetector;

/**
 * Reads Bricks design system inventory without deserializing element trees.
 */
class OrientationGateway
{
    private const BRICKS_CONTENT_META_KEY = '_bricks_page_content_2';

    /**
     * @return array<string, mixed>
     */
    public function getOverview(): array
    {
        return [
            'bricks_version' => BricksEnv::version(),
            'meets_floor'    => BricksEnv::meetsFloor(),
            'css_loading'    => BricksEnv::cssLoadingMode(),
            'counts'         => [
                'global_classes' => $this->countOptionItems('bricks_global_classes'),
                'variables'      => $this->countOptionItems('bricks_global_variables'),
                'theme_styles'   => $this->countOptionItems('bricks_theme_styles'),
                'components'     => $this->countOptionItems('bricks_components'),
                'templates'      => $this->countPublishedPosts('bricks_template'),
                'bricks_pages'   => $this->countBricksPages(),
            ],
            'index'              => [
                'built'    => (new IndexReader())->isBuilt(),
                'coverage' => (new IndexReader())->coverage(),
            ],
            'design_convention'  => DesignConventionStore::get(),
            'detected_framework' => (new ExternalFrameworkDetector())->detect(),
            'convention_active'  => DesignConventionStore::hasConvention(),
        ];
    }

    private function countOptionItems(string $optionName): int
    {
        $value = get_option($optionName, []);

        if (!is_array($value)) {
            return 0;
        }

        return count($value);
    }

    private function countPublishedPosts(string $postType): int
    {
        $counts = wp_count_posts($postType);

        if (!is_object($counts) || !isset($counts->publish)) {
            return 0;
        }

        return (int) $counts->publish;
    }

    private function countBricksPages(): int
    {
        global $wpdb;

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $count = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(DISTINCT pm.post_id) FROM {$wpdb->postmeta} pm INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value <> '' AND p.post_type <> %s AND p.post_status <> %s",
                self::BRICKS_CONTENT_META_KEY,
                'revision',
                'inherit'
            )
        );

        return (int) $count;
    }
}
