<?php

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound -- APD is the established namespace shared with the Pro add-on and retained for backward compatibility.
namespace APD\Admin;

use APD\Repositories\ProductConfigRepository;
use APD\Support\CommercialRuntimeConfig;
use APD\Support\DesignerAssets;

defined('ABSPATH') || exit;

final class AdminOverview
{
    private static ?array $snapshot = null;

    public static function snapshot() : array
    {
        if (self::$snapshot !== null) {
            return self::$snapshot;
        }

        $settings = (new AdminSettings())->all();
        $commercial = new CommercialRuntimeConfig();
        $runtime = $commercial->build($settings);
        $licenseConfig = is_array($runtime['license'] ?? null) ? $runtime['license'] : [];
        $entitlements = $commercial->entitlementsFromLicense($licenseConfig);
        $payload = is_array($entitlements['payload'] ?? null) ? $entitlements['payload'] : [];
        $features = array_filter(
            is_array($entitlements['features'] ?? null) ? $entitlements['features'] : [],
            static fn($enabled) : bool => (bool) $enabled
        );

        $postCounts = wp_count_posts('apd_product_config');
        $publishedConfigs = (int) ($postCounts->publish ?? 0);
        $draftConfigs = (int) ($postCounts->draft ?? 0);
        $bindings = self::bindingSummary();
        $production = self::productionSummary();

        self::$snapshot = [
            'settings' => $settings,
            'pluginVersion' => ASUKA_PRODUCT_DESIGNER_VERSION,
            'designerVersion' => DesignerAssets::designerVersion(),
            'woocommerce' => [
                'active' => class_exists('WooCommerce') && function_exists('WC'),
            ],
            'license' => [
                'enabled' => ! empty($licenseConfig['enabled']),
                'configured' => ! empty($licenseConfig['configured']),
                'active' => ! empty($payload['active']),
                'plan' => sanitize_key((string) ($entitlements['plan'] ?? 'free')) ?: 'free',
                'features' => $features,
                'featureCount' => count($features),
                'payload' => $payload,
                'expiresAt' => trim((string) ($payload['expiresAt'] ?? '')),
                'domain' => trim((string) ($licenseConfig['domain'] ?? '')),
                'apiUrl' => $commercial->apiBaseUrl(),
            ],
            'configs' => [
                'published' => $publishedConfigs,
                'draft' => $draftConfigs,
                'total' => $publishedConfigs + $draftConfigs,
                'recent' => array_slice((new ProductConfigRepository())->allForSelect(), 0, 5),
            ],
            'bindings' => $bindings,
            'production' => $production,
        ];

        return self::$snapshot;
    }

    private static function bindingSummary() : array
    {
        global $wpdb;

        if (! isset($wpdb->posts, $wpdb->postmeta)) {
            return ['count' => 0, 'firstProductId' => 0, 'firstProductUrl' => ''];
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- A request-local snapshot caches this prepared aggregate and avoids loading every product binding into PHP.
        $count = (int) $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(DISTINCT CASE WHEN p.post_type = 'product_variation' THEN p.post_parent ELSE p.ID END)
                 FROM %i p
                 INNER JOIN %i pm ON pm.post_id = p.ID
                 WHERE pm.meta_key = %s
                    AND CAST(pm.meta_value AS UNSIGNED) > 0
                    AND p.post_type IN ('product', 'product_variation')
                    AND p.post_status NOT IN ('trash', 'auto-draft')",
                $wpdb->posts,
                $wpdb->postmeta,
                '_apd_custom_product_id'
            )
        );

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- A request-local snapshot caches this prepared aggregate and avoids loading every product binding into PHP.
        $firstProductId = (int) $wpdb->get_var(
            $wpdb->prepare(
                "SELECT CASE WHEN p.post_type = 'product_variation' THEN p.post_parent ELSE p.ID END
                 FROM %i p
                 INNER JOIN %i pm ON pm.post_id = p.ID
                 WHERE pm.meta_key = %s
                    AND CAST(pm.meta_value AS UNSIGNED) > 0
                    AND p.post_type IN ('product', 'product_variation')
                    AND p.post_status NOT IN ('trash', 'auto-draft')
                 ORDER BY p.post_modified_gmt DESC, p.ID DESC
                 LIMIT 1",
                $wpdb->posts,
                $wpdb->postmeta,
                '_apd_custom_product_id'
            )
        );

        return [
            'count' => $count,
            'firstProductId' => $firstProductId,
            'firstProductUrl' => $firstProductId > 0 ? (string) get_permalink($firstProductId) : '',
        ];
    }

    private static function productionSummary() : array
    {
        global $wpdb;

        $table = isset($wpdb->prefix) ? $wpdb->prefix . 'woocommerce_order_itemmeta' : '';
        if ($table === '' || ! class_exists('WooCommerce')) {
            return ['total' => 0, 'pending' => 0];
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- This read-only WooCommerce table probe is cached in the request-local overview snapshot.
        $tableExists = (string) $wpdb->get_var(
            $wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($table))
        );
        if ($tableExists !== $table) {
            return ['total' => 0, 'pending' => 0];
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- This prepared aggregate is cached in the request-local overview snapshot.
        $total = (int) $wpdb->get_var(
            $wpdb->prepare(
                'SELECT COUNT(*) FROM %i WHERE meta_key = %s AND CAST(meta_value AS UNSIGNED) > 0',
                $table,
                '_apd_config_id'
            )
        );
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- This prepared aggregate is cached in the request-local overview snapshot.
        $pending = (int) $wpdb->get_var(
            $wpdb->prepare(
                'SELECT COUNT(*) FROM %i WHERE meta_key = %s AND meta_value = %s',
                $table,
                '_apd_production_status',
                'pending'
            )
        );

        return [
            'total' => $total,
            'pending' => $pending,
        ];
    }
}
