<?php
/**
 * Local CSS Cache Queue
 *
 * Queues locally hosted stylesheets for background minification and caching.
 * This does NOT fetch or download external CSS.
 *
 * @package ProRank\SEO\Core\Tasks
 * @since   1.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\Tasks;

defined( 'ABSPATH' ) || exit;

/**
 * LocalCssCacheQueue class
 */
class LocalCssCacheQueue {

    /**
     * Cache generation task
     *
     * @var CssCacheGenerationTask
     */
    private CssCacheGenerationTask $cache_task;

    /**
     * Cleanup task
     *
     * @var CssCacheCleanupTask
     */
    private CssCacheCleanupTask $cleanup_task;

    /**
     * Constructor
     */
    public function __construct() {
        $this->cache_task = new CssCacheGenerationTask();
        $this->cleanup_task = new CssCacheCleanupTask();
    }

    /**
     * Initialize hooks
     *
     * @return void
     */
    public function init(): void {
        // Register Action Scheduler callbacks
        $this->cache_task->init();
        $this->cleanup_task->init();

        // Queue local styles late so most styles are registered.
        add_action( 'wp_enqueue_scripts', [ $this, 'queue_local_styles' ], 999 );
    }

    /**
     * Queue local stylesheets for caching.
     *
     * @return void
     */
    public function queue_local_styles(): void {
        if ( is_admin() || wp_doing_ajax() ) {
            return;
        }

        $settings = get_option( 'prorank_cache_settings', [] );
        $enabled = ! empty( $settings['css_minify'] ) || ! empty( $settings['css_combine'] );
        if ( ! $enabled ) {
            return;
        }

        global $wp_styles;
        if ( ! $wp_styles || ! is_object( $wp_styles ) ) {
            return;
        }

        $handles = $wp_styles->queue ?: array_keys( (array) $wp_styles->registered );
        if ( empty( $handles ) ) {
            return;
        }

        $files = [];
        foreach ( $handles as $handle ) {
            $style = $wp_styles->registered[ $handle ] ?? null;
            if ( ! $style || empty( $style->src ) || ! is_string( $style->src ) ) {
                continue;
            }

            $file_path = $this->map_local_url_to_path( $style->src );
            if ( $file_path ) {
                $files[] = $file_path;
            }
        }

        $files = array_values( array_unique( $files ) );
        if ( empty( $files ) ) {
            return;
        }

        $hash = md5( implode( '|', $files ) );
        $cache_key = 'prorank_css_cache_queue_hash';
        $last_hash = get_transient( $cache_key );
        if ( $last_hash === $hash ) {
            return;
        }
        set_transient( $cache_key, $hash, 6 * HOUR_IN_SECONDS );

        $this->cache_task->queue_files( $files );
    }

    /**
     * Map a local stylesheet URL to a filesystem path.
     *
     * @param string $src Stylesheet URL.
     * @return string|null
     */
    private function map_local_url_to_path( string $src ): ?string {
        $src = $this->normalize_src( $src );
        if ( $src === '' ) {
            return null;
        }

        $parsed = wp_parse_url( $src );
        if ( ! is_array( $parsed ) ) {
            return null;
        }

        $site_host = wp_parse_url( home_url( '/' ), PHP_URL_HOST );
        $src_host = $parsed['host'] ?? '';

        if ( $src_host && $site_host && strcasecmp( $src_host, $site_host ) !== 0 ) {
            return null;
        }

        $path = $parsed['path'] ?? '';
        if ( $path === '' || strpos( $path, '.css' ) === false ) {
            return null;
        }

        $site_path = wp_parse_url( home_url( '/' ), PHP_URL_PATH ) ?? '/';
        if ( $site_path !== '/' && strpos( $path, $site_path ) === 0 ) {
            $path = substr( $path, strlen( $site_path ) );
        }

        $path = ltrim( $path, '/' );
        if ( $path === '' || strpos( $path, '..' ) !== false ) {
            return null;
        }

        $home_path = function_exists( 'prorank_get_home_path' ) ? prorank_get_home_path() : '';
        if ( $home_path === '' ) {
            return null;
        }

        $file_path = wp_normalize_path( $home_path . $path );
        if ( ! file_exists( $file_path ) || ! is_readable( $file_path ) ) {
            return null;
        }

        return $file_path;
    }

    /**
     * Normalize stylesheet source to an absolute URL when possible.
     *
     * @param string $src Stylesheet source.
     * @return string
     */
    private function normalize_src( string $src ): string {
        $src = trim( $src );
        if ( $src === '' ) {
            return '';
        }

        if ( strpos( $src, '//' ) === 0 ) {
            $src = ( is_ssl() ? 'https:' : 'http:' ) . $src;
        } elseif ( strpos( $src, '/' ) === 0 ) {
            $src = home_url( $src );
        }

        return $src;
    }
}
