<?php
/**
 * Plugin Name:       Kitgenix PDF Invoicing for WooCommerce
 * Plugin URI:        https://wordpress.org/plugins/kitgenix-pdf-invoicing-for-woocommerce/
 * Author Plugin URI: https://kitgenix.com/plugins/kitgenix-pdf-invoicing-for-woocommerce
 * Documentation URI: https://kitgenix.com/plugins/kitgenix-pdf-invoicing-for-woocommerce/documentation
 * Support URI:       https://wordpress.org/support/plugin/kitgenix-pdf-invoicing-for-woocommerce/
 * Author Support URI: https://kitgenix.com/plugins/kitgenix-pdf-invoicing-for-woocommerce/support
 * Feature Request URI: https://kitgenix.com/plugins/kitgenix-pdf-invoicing-for-woocommerce/feature-request
 * Description:       Generate WooCommerce PDF invoices, receipts, packing slips, and credit notes with secure downloads and configurable email attachments.
 * Version:           2.0.0
 * Requires at least: 6.0
 * Tested up to:      7.1
 * Requires PHP:      8.1
 * Author:            Kitgenix
 * Author URI:        https://kitgenix.com/
 * Donate link:       https://www.paypal.com/donate/?hosted_button_id=KALF36K6JJ9B2
 * Requires Plugins:  woocommerce
 * WC requires at least: 10.0
 * WC tested up to:   11.0.1
 * License:           GPLv3 or later
 * License URI:       https://www.gnu.org/licenses/gpl-3.0.html
 * Text Domain:       kitgenix-pdf-invoicing-for-woocommerce
 * Domain Path:       /languages
 */

defined( 'ABSPATH' ) || exit;

if ( ! defined( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_FILE' ) ) {
    define( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_FILE', __FILE__ );
}
if ( ! defined( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_PATH' ) ) {
    define( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_PATH', plugin_dir_path( __FILE__ ) );
}
if ( ! defined( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_URL' ) ) {
    define( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_URL', plugin_dir_url( __FILE__ ) );
}
if ( ! defined( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_VERSION' ) ) {
    define( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_VERSION', '2.0.0' );
}

// -----------------------------------------------------------------------------
// Shared Kitgenix admin menu (top-level) helper.
// Each Kitgenix plugin may call this; it is safe to call multiple times.
// -----------------------------------------------------------------------------
if ( ! function_exists( 'kitgenix_get_admin_menu_icon' ) ) {
    function kitgenix_get_admin_menu_icon( string $plugin_file ): string {
        $plugin_dir = dirname( $plugin_file ) . '/';
        $icon_paths = [
            $plugin_dir . 'assets/images/logos/kitgenix-wordpress-admin-menu-favicon.svg',
            $plugin_dir . 'assets/images/logos/kitgenix-black-favicon.svg',
        ];

        foreach ( $icon_paths as $icon_path ) {
            if ( ! is_readable( $icon_path ) ) {
                continue;
            }

            $svg = file_get_contents( $icon_path );
            if ( false !== $svg && '' !== trim( $svg ) ) {
                return 'data:image/svg+xml;base64,' . base64_encode( $svg );
            }
        }

        return 'dashicons-admin-generic';
    }
}

if ( ! function_exists( 'kitgenix_ensure_admin_menu' ) ) {
    function kitgenix_ensure_admin_menu(): void {
        if ( ! is_admin() ) {
            return;
        }

        global $admin_page_hooks;
        $slug = 'kitgenix';

        if ( isset( $admin_page_hooks[ $slug ] ) ) {
            return;
        }

        // Prefer WooCommerce managers when WooCommerce is active, otherwise admins.
        $capability = class_exists( 'WooCommerce' ) ? 'manage_woocommerce' : 'manage_options';
        if ( ! current_user_can( $capability ) && current_user_can( 'manage_options' ) ) {
            $capability = 'manage_options';
        }

        $icon_url = kitgenix_get_admin_menu_icon( __FILE__ );

        add_menu_page(
            __( 'Kitgenix', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            __( 'Kitgenix', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            $capability,
            $slug,
            'kitgenix_render_admin_page',
            $icon_url,
            58
        );
    }
}

// Ensure the shared Kitgenix top-level menu exists.
add_action( 'admin_menu', 'kitgenix_ensure_admin_menu', 5 );

if ( ! function_exists( 'kitgenix_hub_get_wporg_active_installs' ) ) {
    /**
     * Fetch WP.org active install counts for a set of plugin slugs.
     * Cached to avoid repeated network calls.
     *
     * @param string[] $slugs
     * @return array<string,int> Map of slug => active_installs
     */
    function kitgenix_hub_get_wporg_active_installs( array $slugs ): array {
        if ( ! function_exists( 'get_transient' ) || ! function_exists( 'set_transient' ) ) {
            return [];
        }

        $clean_slugs = [];
        foreach ( $slugs as $slug ) {
            $slug = is_string( $slug ) ? $slug : '';
            $slug = function_exists( 'sanitize_key' ) ? sanitize_key( $slug ) : strtolower( preg_replace( '/[^a-z0-9_\-]/', '', $slug ) );
            if ( $slug ) {
                $clean_slugs[] = $slug;
            }
        }

        $clean_slugs = array_values( array_unique( $clean_slugs ) );
        if ( empty( $clean_slugs ) ) {
            return [];
        }

        $cache_key = 'kitgenix_hub_wporg_active_installs_v1';
        $cached    = get_transient( $cache_key );
        $cached    = is_array( $cached ) ? $cached : [];

        $missing = [];
        foreach ( $clean_slugs as $slug ) {
            if ( ! array_key_exists( $slug, $cached ) ) {
                $missing[] = $slug;
            }
        }

        if ( ! empty( $missing ) ) {
            if ( ! function_exists( 'plugins_api' ) ) {
                require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
            }

            foreach ( $missing as $slug ) {
                $info = plugins_api(
                    'plugin_information',
                    [
                        'slug'   => $slug,
                        'fields' => [
                            'active_installs'   => true,
                            'short_description' => false,
                            'description'       => false,
                            'sections'          => false,
                            'versions'          => false,
                            'banners'           => false,
                            'rating'            => false,
                            'ratings'           => false,
                            'downloaded'        => false,
                            'last_updated'      => false,
                            'added'             => false,
                            'tags'              => false,
                            'requires'          => false,
                            'requires_php'      => false,
                            'tested'            => false,
                            'homepage'          => false,
                            'donate_link'       => false,
                        ],
                    ]
                );

                if ( function_exists( 'is_wp_error' ) && is_wp_error( $info ) ) {
                    continue;
                }

                if ( is_object( $info ) && isset( $info->active_installs ) ) {
                    $cached[ $slug ] = (int) $info->active_installs;
                }
            }

            $ttl = defined( 'DAY_IN_SECONDS' ) ? (int) DAY_IN_SECONDS : 86400;
            set_transient( $cache_key, $cached, $ttl );
        }

        $result = [];
        foreach ( $clean_slugs as $slug ) {
            if ( isset( $cached[ $slug ] ) && (int) $cached[ $slug ] > 0 ) {
                $result[ $slug ] = (int) $cached[ $slug ];
            }
        }

        return $result;
    }
}

if ( ! function_exists( 'kitgenix_hub_get_wporg_ratings' ) ) {
    /**
     * Fetch WP.org ratings (percentage) for a set of plugin slugs.
     *
     * @param array<int,string> $slugs Plugin slugs.
     * @return array<string,int> Map of slug => rating percentage (0-100)
     */
    function kitgenix_hub_get_wporg_ratings( array $slugs ): array {
        $slugs = array_values( array_unique( array_filter( array_map( 'strval', $slugs ) ) ) );
        if ( empty( $slugs ) ) {
            return [];
        }

        $cache_key = 'kitgenix_hub_wporg_ratings_v1';
        $cached = get_transient( $cache_key );
        if ( is_array( $cached ) ) {
            $missing = array_diff( $slugs, array_keys( $cached ) );
            if ( empty( $missing ) ) {
                return $cached;
            }
        } else {
            $cached = [];
            $missing = $slugs;
        }

        if ( ! function_exists( 'plugins_api' ) ) {
            require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
        }

        foreach ( $missing as $slug ) {
            $info = plugins_api(
                'plugin_information',
                [
                    'slug'   => $slug,
                    'fields' => [
                        'rating' => true,
                    ],
                ]
            );

            if ( is_object( $info ) && isset( $info->rating ) ) {
                $cached[ $slug ] = (int) $info->rating;
            }
        }

        set_transient( $cache_key, $cached, DAY_IN_SECONDS );

        return $cached;
    }
}

if ( ! function_exists( 'kitgenix_hub_get_wporg_media' ) ) {
    /**
     * Fetch WP.org banner or icon artwork for a set of plugin slugs.
     *
     * @param array<int,string> $slugs Plugin slugs.
     * @return array<string,array{url:string,type:string}> Map of slug => media payload.
     */
    function kitgenix_hub_get_wporg_media( array $slugs ): array {
        if ( ! function_exists( 'get_transient' ) || ! function_exists( 'set_transient' ) ) {
            return [];
        }

        $slugs = array_values( array_unique( array_filter( array_map( 'strval', $slugs ) ) ) );
        if ( empty( $slugs ) ) {
            return [];
        }

        $cache_key = 'kitgenix_hub_wporg_media_v1';
        $cached    = get_transient( $cache_key );
        $cached    = is_array( $cached ) ? $cached : [];
        $missing   = array_diff( $slugs, array_keys( $cached ) );

        if ( ! empty( $missing ) ) {
            if ( ! function_exists( 'plugins_api' ) ) {
                require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
            }

            foreach ( $missing as $slug ) {
                $info = plugins_api(
                    'plugin_information',
                    [
                        'slug'   => $slug,
                        'fields' => [
                            'icons'             => true,
                            'banners'           => true,
                            'active_installs'   => false,
                            'rating'            => false,
                            'ratings'           => false,
                            'short_description' => false,
                            'description'       => false,
                            'sections'          => false,
                            'versions'          => false,
                            'downloaded'        => false,
                            'last_updated'      => false,
                            'added'             => false,
                            'tags'              => false,
                            'requires'          => false,
                            'requires_php'      => false,
                            'tested'            => false,
                            'homepage'          => false,
                            'donate_link'       => false,
                        ],
                    ]
                );

                if ( function_exists( 'is_wp_error' ) && is_wp_error( $info ) ) {
                    continue;
                }

                $media_url  = '';
                $media_type = '';

                if ( is_object( $info ) && isset( $info->banners ) ) {
                    $banners = is_object( $info->banners ) ? get_object_vars( $info->banners ) : ( is_array( $info->banners ) ? $info->banners : [] );
                    foreach ( [ 'high', 'low' ] as $key ) {
                        if ( ! empty( $banners[ $key ] ) && is_string( $banners[ $key ] ) ) {
                            $media_url  = $banners[ $key ];
                            $media_type = 'banner';
                            break;
                        }
                    }
                }

                if ( '' === $media_url && is_object( $info ) && isset( $info->icons ) ) {
                    $icons = is_object( $info->icons ) ? get_object_vars( $info->icons ) : ( is_array( $info->icons ) ? $info->icons : [] );
                    foreach ( [ 'svg', '2x', '1x', 'default' ] as $key ) {
                        if ( ! empty( $icons[ $key ] ) && is_string( $icons[ $key ] ) ) {
                            $media_url  = $icons[ $key ];
                            $media_type = 'icon';
                            break;
                        }
                    }
                }

                $cached[ $slug ] = $media_url ? [
                    'url'  => $media_url,
                    'type' => $media_type,
                ] : [];
            }

            $ttl = defined( 'DAY_IN_SECONDS' ) ? (int) DAY_IN_SECONDS : 86400;
            set_transient( $cache_key, $cached, $ttl );
        }

        $result = [];
        foreach ( $slugs as $slug ) {
            if ( ! empty( $cached[ $slug ]['url'] ) ) {
                $result[ $slug ] = [
                    'url'  => (string) $cached[ $slug ]['url'],
                    'type' => ! empty( $cached[ $slug ]['type'] ) ? (string) $cached[ $slug ]['type'] : 'icon',
                ];
            }
        }

        return $result;
    }
}

if ( ! function_exists( 'kitgenix_render_admin_page' ) ) {
    function kitgenix_render_admin_page(): void {
        $allowed = current_user_can( 'manage_options' ) || ( class_exists( 'WooCommerce' ) && current_user_can( 'manage_woocommerce' ) );
        if ( ! $allowed ) {
            wp_die( esc_html__( 'Sorry, you are not allowed to access this page.', 'kitgenix-pdf-invoicing-for-woocommerce' ) );
        }

        if ( ! function_exists( 'is_plugin_active' ) ) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        $plugins_data = function_exists( 'get_plugins' ) ? get_plugins() : [];

        $plugins = [
            [
                'id'       => 'turnstile',
                'name'     => __( 'CAPTCHA for Cloudflare Turnstile', 'kitgenix-pdf-invoicing-for-woocommerce' ),
                'slug'     => 'kitgenix-captcha-for-cloudflare-turnstile',
                'file'     => 'kitgenix-captcha-for-cloudflare-turnstile/kitgenix-captcha-for-cloudflare-turnstile.php',
                'page'     => 'kitgenix-captcha-for-cloudflare-turnstile',
                'requires' => __( 'Add Cloudflare Turnstile CAPTCHA to WordPress, WooCommerce, Elementor, and popular form plugins.', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            ],
            [
                'id'       => 'custom_tabs',
                'name'     => __( 'Custom Tabs for WooCommerce', 'kitgenix-pdf-invoicing-for-woocommerce' ),
                'slug'     => 'kitgenix-custom-tabs-for-woocommerce',
                'file'     => 'kitgenix-custom-tabs-for-woocommerce/kitgenix-custom-tabs-for-woocommerce.php',
                'page'     => 'kitgenix-custom-tabs-for-woocommerce',
                'requires' => __( 'Add custom WooCommerce product tabs with per-product content, global tabs, and lightweight controls.', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            ],
            [
                'id'       => 'documents',
                'name'     => __( 'Document Manager', 'kitgenix-pdf-invoicing-for-woocommerce' ),
                'slug'     => 'kitgenix-document-manager',
                'file'     => 'kitgenix-document-manager/kitgenix-document-manager.php',
                'page'     => 'kitgenix-document-manager',
                'requires' => __( 'Manage document downloads with stable links, version history, and private file access.', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            ],
            [
                'id'       => 'tracking',
                'name'     => __( 'Order Tracking for WooCommerce', 'kitgenix-pdf-invoicing-for-woocommerce' ),
                'slug'     => 'kitgenix-order-tracking-for-woocommerce',
                'file'     => 'kitgenix-order-tracking-for-woocommerce/kitgenix-order-tracking-for-woocommerce.php',
                'page'     => 'kitgenix-order-tracking-for-woocommerce-analytics',
                'requires' => __( 'Add WooCommerce order tracking, multi-shipment support, email tracking links, and a public customer tracking page.', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            ],
            [
                'id'       => 'pdf',
                'name'     => __( 'PDF Invoicing for WooCommerce', 'kitgenix-pdf-invoicing-for-woocommerce' ),
                'slug'     => 'kitgenix-pdf-invoicing-for-woocommerce',
                'file'     => 'kitgenix-pdf-invoicing-for-woocommerce/kitgenix-pdf-invoicing-for-woocommerce.php',
                'page'     => 'kitgenix-pdf-invoicing-settings',
                'requires' => __( 'Generate WooCommerce PDF invoices, receipts, packing slips, and credit notes with secure downloads and configurable email attachments.', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            ],
            [
                'id'       => 'stock',
                'name'     => __( 'Stock Sync for WooCommerce', 'kitgenix-pdf-invoicing-for-woocommerce' ),
                'slug'     => 'kitgenix-stock-sync-for-woocommerce',
                'file'     => 'kitgenix-stock-sync-for-woocommerce/kitgenix-stock-sync-for-woocommerce.php',
                'page'     => 'kitgenix-stock-sync-for-woocommerce',
                'requires' => __( 'Sync WooCommerce stock between stores with secure master-child inventory updates and signed REST requests.', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            ],
            [
                'id'       => 'multistore',
                'name'     => __( 'MultiStore for WooCommerce', 'kitgenix-pdf-invoicing-for-woocommerce' ),
                'slug'     => 'kitgenix-multistore-sync-for-woocommerce',
                'file'     => 'kitgenix-multistore-sync-for-woocommerce/kitgenix-multistore-sync-for-woocommerce.php',
                'page'     => 'kitgenix-multistore-sync-for-woocommerce',
                'requires' => __( 'Sync WooCommerce products, prices, media, and metadata between multiple stores with a secure master-child architecture.', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            ],
            [
                'id'       => 'image_optimizer',
                'name'     => __( 'Image Optimizer', 'kitgenix-pdf-invoicing-for-woocommerce' ),
                'slug'     => 'kitgenix-image-optimizer',
                'file'     => 'kitgenix-image-optimizer/kitgenix-image-optimizer.php',
                'page'     => 'kitgenix-image-optimizer',
                'requires' => __( 'Optimize, compress, and resize images in your WordPress media library with automatic on-upload processing and bulk optimization tools.', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            ],
            [
                'id'       => 'affiliate',
                'name'     => __( 'Affiliate Link Manager', 'kitgenix-pdf-invoicing-for-woocommerce' ),
                'slug'     => 'kitgenix-affiliate-link-manager',
                'file'     => 'kitgenix-affiliate-link-manager/kitgenix-affiliate-link-manager.php',
                'page'     => 'kitgenix-affiliate-link-manager',
                'requires' => __( 'Manage affiliate short links, branded redirects, and click tracking from one WordPress dashboard.', 'kitgenix-pdf-invoicing-for-woocommerce' ),
            ],
        ];

        $slugs = [];
        foreach ( $plugins as $plugin ) {
            if ( ! empty( $plugin['slug'] ) ) {
                $slugs[] = (string) $plugin['slug'];
            }
        }
        $wporg_active_installs = kitgenix_hub_get_wporg_active_installs( $slugs );
        $wporg_ratings        = kitgenix_hub_get_wporg_ratings( $slugs );
        $wporg_media          = kitgenix_hub_get_wporg_media( $slugs );
        $logo_url             = plugins_url( 'assets/images/logos/kitgenix-primary-favicon.svg', __FILE__ );

        echo '<div class="wrap kitgenix-admin-app plugin-install-php">'
            . '<div class="kitgenix-hub-header">'
            . '<div class="kitgenix-hub-brand">'
            . '<span class="kitgenix-topbar-brand">'
            . '<img class="kitgenix-hub-logo" src="' . esc_url( $logo_url ) . '" alt="' . esc_attr__( 'Kitgenix', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '" width="30" height="30" />'
            . '</span>'
            . '<span class="kitgenix-topbar-divider" aria-hidden="true"></span>'
            . '<div class="kitgenix-hub-brand-copy">'
            . '<h1 class="kitgenix-hub-title">' . esc_html__( 'Kitgenix', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</h1>'
            . '<p class="kitgenix-hub-description">' . esc_html__( 'Install, activate, open, and review Kitgenix plugins.', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</p>'
            . '</div>'
            . '</div>'
            . '<div class="kitgenix-hub-social-links">'
            . '<a href="https://kitgenix.com" target="_blank" rel="noopener noreferrer" aria-label="Website" title="Website"><img src="' . esc_url( plugins_url( 'assets/images/social-media/globe-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">Website</span></a>'
            . '<a href="https://www.facebook.com/groups/kitgenix" target="_blank" rel="noopener noreferrer" aria-label="Facebook Community" title="Facebook Community"><img src="' . esc_url( plugins_url( 'assets/images/social-media/facebook-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">Facebook Community</span></a>'
            . '<a href="https://www.facebook.com/kitgenix" target="_blank" rel="noopener noreferrer" aria-label="Facebook" title="Facebook"><img src="' . esc_url( plugins_url( 'assets/images/social-media/facebook-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">Facebook</span></a>'
            . '<a href="https://www.instagram.com/kitgenix/" target="_blank" rel="noopener noreferrer" aria-label="Instagram" title="Instagram"><img src="' . esc_url( plugins_url( 'assets/images/social-media/instagram-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">Instagram</span></a>'
            . '<a href="https://www.youtube.com/@Kitgenix" target="_blank" rel="noopener noreferrer" aria-label="YouTube" title="YouTube"><img src="' . esc_url( plugins_url( 'assets/images/social-media/youtube-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">YouTube</span></a>'
            . '<a href="https://www.reddit.com/r/Kitgenix/" target="_blank" rel="noopener noreferrer" aria-label="Reddit" title="Reddit"><img src="' . esc_url( plugins_url( 'assets/images/social-media/reddit-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">Reddit</span></a>'
            . '<a href="https://www.linkedin.com/company/kitgenix" target="_blank" rel="noopener noreferrer" aria-label="LinkedIn" title="LinkedIn"><img src="' . esc_url( plugins_url( 'assets/images/social-media/linkedin-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">LinkedIn</span></a>'
            . '<a href="https://x.com/kitgenix" target="_blank" rel="noopener noreferrer" aria-label="X" title="X"><img src="' . esc_url( plugins_url( 'assets/images/social-media/x-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">X</span></a>'
            . '<a href="https://www.tiktok.com/@kitgenix" target="_blank" rel="noopener noreferrer" aria-label="TikTok" title="TikTok"><img src="' . esc_url( plugins_url( 'assets/images/social-media/tiktok-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">TikTok</span></a>'
            . '<a href="https://github.com/kitgenix" target="_blank" rel="noopener noreferrer" aria-label="GitHub" title="GitHub"><img src="' . esc_url( plugins_url( 'assets/images/social-media/github-solid.svg', __FILE__ ) ) . '" alt="" width="13" height="13" aria-hidden="true" /><span class="screen-reader-text">GitHub</span></a>'
            . '</div>'
            . '</div>'
            . '<div class="kitgenix-hub-wrap">'
            . '<div class="kitgenix-hub">'
            . '<div class="kitgenix-hub-grid">';
        foreach ( $plugins as $p ) {
            $id = (string) $p['id'];
            $file = (string) $p['file'];
            $installed = isset( $plugins_data[ $file ] );
            $active = false;
            if ( $installed && function_exists( 'is_plugin_active' ) ) {
                $active = is_plugin_active( $file ) || ( function_exists( 'is_plugin_active_for_network' ) && is_plugin_active_for_network( $file ) );
            }

            $version_badge = '';
            if ( $installed && ! empty( $plugins_data[ $file ]['Version'] ) ) {
                $version_badge = '<span class="kitgenix-badge muted">v' . esc_html( (string) $plugins_data[ $file ]['Version'] ) . '</span>';
            }

            $installs_badge = '';
            $slug = ! empty( $p['slug'] ) ? (string) $p['slug'] : '';
            if ( $slug && ! empty( $wporg_active_installs[ $slug ] ) ) {
                $count = (int) $wporg_active_installs[ $slug ];
                $count_text = function_exists( 'number_format_i18n' ) ? number_format_i18n( $count ) : (string) $count;
                /* translators: %s is the number of active installs and may include a thousands separator, e.g. "1,234". The "+" suffix is literal. */
                $installs_badge = '<span class="kitgenix-badge muted">' . esc_html( sprintf( __( '%s+ installs', 'kitgenix-pdf-invoicing-for-woocommerce' ), $count_text ) ) . '</span>';
            }

            $rating_badge = '';
            if ( $slug && isset( $wporg_ratings[ $slug ] ) && (int) $wporg_ratings[ $slug ] > 0 ) {
                $rating_percent = (int) $wporg_ratings[ $slug ];
                $stars = ( $rating_percent / 100 ) * 5;
                $stars_text = function_exists( 'number_format_i18n' ) ? number_format_i18n( $stars, 1 ) : number_format( $stars, 1 );
                /* translators: %s is the average rating out of 5 with one decimal place, e.g. "4.5". The star symbol (★) precedes the number. */
                $rating_badge = '<span class="kitgenix-badge muted">' . esc_html( sprintf( __( '★ %s/5', 'kitgenix-pdf-invoicing-for-woocommerce' ), $stars_text ) ) . '</span>';
            }

            $status_badge = '';
            if ( ! $installed ) {
                $status_badge = '<span class="kitgenix-badge muted">' . esc_html__( 'Not installed', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</span>';
            } elseif ( $active ) {
                $status_badge = '<span class="kitgenix-badge ok">' . esc_html__( 'Active', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</span>';
            } else {
                $status_badge = '<span class="kitgenix-badge warn">' . esc_html__( 'Installed (Inactive)', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</span>';
            }

            $card_media = '';
            if ( $slug && ! empty( $wporg_media[ $slug ]['url'] ) ) {
                $media_type = ( ! empty( $wporg_media[ $slug ]['type'] ) && 'banner' === (string) $wporg_media[ $slug ]['type'] ) ? 'banner' : 'icon';
                $card_media = '<div class="kitgenix-card-media kitgenix-card-media-' . esc_attr( $media_type ) . '"><img class="kitgenix-card-media-image" src="' . esc_url( (string) $wporg_media[ $slug ]['url'] ) . '" alt="" loading="lazy" /></div>';
            }

            $actions = '';
            if ( ! $installed ) {
                if ( current_user_can( 'install_plugins' ) ) {
                    $install_url = wp_nonce_url(
                        admin_url( 'update.php?action=install-plugin&plugin=' . rawurlencode( (string) $p['slug'] ) ),
                        'install-plugin_' . (string) $p['slug']
                    );
                    $actions .= '<a class="button button-primary" href="' . esc_url( $install_url ) . '">' . esc_html__( 'Install', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</a>';
                } else {
                    $actions .= '<a class="button button-primary" href="' . esc_url( admin_url( 'plugin-install.php?s=' . rawurlencode( 'kitgenix' ) . '&tab=search&type=term' ) ) . '">' . esc_html__( 'Install', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</a>';
                }
            } elseif ( ! $active ) {
                if ( current_user_can( 'activate_plugins' ) ) {
                    $activate_url = wp_nonce_url(
                        admin_url( 'plugins.php?action=activate&plugin=' . rawurlencode( $file ) . '&plugin_status=all&paged=1&s=' ),
                        'activate-plugin_' . $file
                    );
                    $actions .= '<a class="button button-primary" href="' . esc_url( $activate_url ) . '">' . esc_html__( 'Activate', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</a>';
                } else {
                    $actions .= '<span class="description">' . esc_html__( 'You do not have permission to activate plugins.', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</span>';
                }
            } else {
                $open_url = ! empty( $p['page'] ) ? admin_url( 'admin.php?page=' . rawurlencode( (string) $p['page'] ) ) : '';
                if ( $open_url ) {
                    $actions .= '<a class="button button-primary" href="' . esc_url( $open_url ) . '">' . esc_html__( 'Open', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</a>';
                }
            }

            $info_url = admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . rawurlencode( (string) $p['slug'] ) . '&TB_iframe=true&width=600&height=550' );
            $actions .= ' <a class="button button-secondary thickbox open-plugin-details-modal" href="' . esc_url( $info_url ) . '">' . esc_html__( 'Details', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</a>';
            if ( $slug ) {
                $review_url  = 'https://wordpress.org/support/plugin/' . rawurlencode( $slug ) . '/reviews/#new-post';
                $support_url = 'https://wordpress.org/support/plugin/' . rawurlencode( $slug ) . '/';
                $actions    .= ' <a class="button button-secondary" href="' . esc_url( $review_url ) . '" target="_blank" rel="noopener noreferrer">' . esc_html__( 'Review', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</a>';
                $actions    .= ' <a class="button button-secondary" href="' . esc_url( $support_url ) . '" target="_blank" rel="noopener noreferrer">' . esc_html__( 'Support Forum', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</a>';
            }

            $allowed_kitgenix_html = [
                'a' => [ 'href' => true, 'class' => true, 'target' => true, 'rel' => true ],
                'span' => [ 'class' => true, 'aria-label' => true ],
                'strong' => [],
            ];

            $card_media_allowed_html = [
                'div' => [ 'class' => true ],
                'img' => [ 'class' => true, 'src' => true, 'alt' => true, 'loading' => true ],
            ];

            echo '<div class="kitgenix-card" data-kitgenix-plugin="' . esc_attr( sanitize_key( $id ) ) . '">'  
                . wp_kses( $card_media, $card_media_allowed_html )
                . '<div class="kitgenix-card-body">'
                . '<div class="kitgenix-card-badges">' . wp_kses( trim( $status_badge . ' ' . $version_badge . ' ' . $rating_badge . ' ' . $installs_badge ), $allowed_kitgenix_html ) . '</div>'
                . '<p class="kitgenix-card-title">' . esc_html( (string) $p['name'] ) . '</p>'
                . '<p class="kitgenix-card-desc">' . esc_html( (string) $p['requires'] ) . '</p>'
                . '</div>'
                . '<div class="kitgenix-card-actions">' . wp_kses( $actions, $allowed_kitgenix_html ) . '</div>'
                . '</div>';
        }

        echo '</div></div></div></div>';
    }
}

if ( ! function_exists( 'kitgenix_pdf_invoicing_register_admin_ui_style' ) ) {
    function kitgenix_pdf_invoicing_register_admin_ui_style(): void {
        if ( ! is_admin() ) {
            return;
        }

        if ( function_exists( 'wp_style_is' ) && wp_style_is( 'kitgenix-pdf-invoicing-for-woocommerce-admin-ui', 'registered' ) ) {
            return;
        }

        $ver      = defined( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_VERSION' ) ? (string) KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_VERSION : '2.0.0';
        $css_file = plugin_dir_path( __FILE__ ) . 'assets/css/kitgenix-admin-ui.css';
        $css_ver  = file_exists( $css_file ) ? (string) filemtime( $css_file ) : $ver;

        wp_register_style( 'kitgenix-pdf-invoicing-for-woocommerce-admin-ui', plugins_url( 'assets/css/kitgenix-admin-ui.css', __FILE__ ), [], $css_ver );
    }
}
add_action( 'admin_enqueue_scripts', 'kitgenix_pdf_invoicing_register_admin_ui_style', 5 );

/**
 * Enqueue Kitgenix hub styles on the top-level Kitgenix page.
 */
function kitgenix_pdf_enqueue_hub_assets( string $hook_suffix ): void {
    // Prefer checking the `page` query arg so assets load reliably across installs.
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
    if ( 'kitgenix' !== $page && 'toplevel_page_kitgenix' !== $hook_suffix ) {
        return;
    }

    add_thickbox();
    wp_enqueue_style( 'plugin-install' );

    if ( function_exists( 'wp_style_is' ) && ( wp_style_is( 'kitgenix-hub', 'enqueued' ) || wp_style_is( 'kitgenix-hub', 'registered' ) ) ) {
        return;
    }

    $ver = defined( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_VERSION' ) ? (string) KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_VERSION : '2.0.0';
    $hub_css_file = defined( 'KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_DIR' ) ? (string) KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_DIR . 'assets/css/kitgenix-hub.css' : '';
    wp_register_style( 'kitgenix-hub', plugins_url( 'assets/css/kitgenix-hub.css', __FILE__ ), [], $ver );
    wp_enqueue_style( 'kitgenix-hub' );

    wp_register_style( 'kitgenix-pdf-invoicing-for-woocommerce-admin-ui', plugins_url( 'assets/css/kitgenix-admin-ui.css', __FILE__ ), [], $ver );
    wp_enqueue_style( 'kitgenix-pdf-invoicing-for-woocommerce-admin-ui' );
}
add_action( 'admin_enqueue_scripts', 'kitgenix_pdf_enqueue_hub_assets' );

// Prevent activation if WooCommerce is not active.
register_activation_hook( __FILE__, static function () {
    if ( ! class_exists( 'WooCommerce' ) ) {
        if ( ! function_exists( 'deactivate_plugins' ) ) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }
        deactivate_plugins( plugin_basename( __FILE__ ) );
        wp_die( esc_html__( 'Kitgenix PDF Invoicing for WooCommerce requires WooCommerce to be installed and active. The plugin has been deactivated.', 'kitgenix-pdf-invoicing-for-woocommerce' ) );
    }

    // Composer autoload is required further down this file; require it here
    // too since activation can run before that point on some hosts.
    $composer_autoload = KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_PATH . 'vendor/autoload.php';
    if ( file_exists( $composer_autoload ) ) {
        require_once $composer_autoload;
    }

    if ( class_exists( \Kitgenix\PDF_Invoicing\Core\Migrations::class ) ) {
        \Kitgenix\PDF_Invoicing\Core\Migrations::run_activation();
    }

    set_transient( 'kitgenix_pdf_invoicing_for_woocommerce_do_activation_redirect', 1, 30 );
} );

/**
 * Perform the activation redirect once.
 */
add_action( 'admin_init', static function () {
    if ( ! get_transient( 'kitgenix_pdf_invoicing_for_woocommerce_do_activation_redirect' ) ) {
        return;
    }
    delete_transient( 'kitgenix_pdf_invoicing_for_woocommerce_do_activation_redirect' );

    // If bulk-activated, don't redirect.
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    if ( isset( $_GET['activate-multi'] ) ) {
        return;
    }

    $target = admin_url( 'admin.php?page=kitgenix-pdf-invoicing-settings' );
    wp_safe_redirect( esc_url_raw( $target ) );
    exit;
} );

register_deactivation_hook( __FILE__, static function () {
    delete_transient( 'kitgenix_pdf_invoicing_for_woocommerce_do_activation_redirect' );
} );

/**
 * "Settings" link on the Plugins screen.
 */
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), static function ( array $links ): array {
    $url = admin_url( 'admin.php?page=kitgenix-pdf-invoicing-settings' );
    $links[] = '<a href="' . esc_url( $url ) . '">' . esc_html__( 'Settings', 'kitgenix-pdf-invoicing-for-woocommerce' ) . '</a>';
    return $links;
} );

/**
 * Composer autoload (PSR-4 + Dompdf).
 */
$kitgenix_pdf_invoicing_for_woocommerce_composer_autoload = KITGENIX_PDF_INVOICING_FOR_WOOCOMMERCE_PATH . 'vendor/autoload.php';
if ( file_exists( $kitgenix_pdf_invoicing_for_woocommerce_composer_autoload ) ) {
    require_once $kitgenix_pdf_invoicing_for_woocommerce_composer_autoload;
} else {
    // Fail gracefully but visibly.
    add_action(
        'admin_notices',
        static function () {
            ?>
            <div class="notice notice-error">
                <p>
                    <?php esc_html_e( 'Kitgenix PDF Invoicing for WooCommerce: Composer autoload not found. Please run "composer install".', 'kitgenix-pdf-invoicing-for-woocommerce' ); ?>
                </p>
            </div>
            <?php
        }
    );
    return;
}

// WooCommerce HPOS (High-Performance Order Storage) compatibility.
// Declare support for custom order tables so WooCommerce doesn't flag the
// plugin as incompatible when HPOS is enabled.
add_action(
    'before_woocommerce_init',
    static function () {
        if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
            \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
                'custom_order_tables',
                __FILE__,
                true
            );
        }
    }
);

add_action(
    'plugins_loaded',
    static function () {
        // Translations are automatically loaded by WordPress.org when hosted there;
        // manual `load_plugin_textdomain()` is no longer required and is discouraged.

        if ( ! class_exists( 'WooCommerce' ) ) {
            add_action(
                'admin_notices',
                static function () {
                    ?>
                    <div class="notice notice-error">
                        <p>
                            <?php esc_html_e( 'Kitgenix PDF Invoicing for WooCommerce requires WooCommerce to be active.', 'kitgenix-pdf-invoicing-for-woocommerce' ); ?>
                        </p>
                    </div>
                    <?php
                }
            );
            return;
        }

        // Idempotent, version-gated upgrade routine (creates/repairs the
        // atomic sequence table, backfills document status/history, seeds
        // the credit-note refund map). Cheap no-op once already current.
        \Kitgenix\PDF_Invoicing\Core\Migrations::maybe_run();

        $plugin = new \Kitgenix\PDF_Invoicing\Core\Plugin();
        $plugin->init();
    }
);
