<?php

namespace StaticDeploy;

class DetectPostsPaginationURLs {

    /**
     * Detect Post pagination URLs
     *
     * @return \Iterator<PathInfo> list of URLs
     */
    public static function detect( string $wp_site_url ): \Iterator {
        if ( STATIC_DEPLOY_DEBUG ) {
            WsLog::d( 'Detecting post pagination URLs' );
        }

        global $wpdb, $wp_rewrite;
        $unique_post_types = [];

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        $posts = $wpdb->get_results(
            $wpdb->prepare(
                'SELECT ID,post_type FROM %i WHERE post_status = %s AND post_type NOT IN (%s,%s)',
                $wpdb->posts,
                'publish',
                'revision',
                'nav_menu_item'
            )
        );

        foreach ( $posts as $post ) {
            // capture all post types
            $unique_post_types[] = $post->post_type;
        }

        // get all pagination links for each post_type
        $post_types = array_unique( $unique_post_types );
        $pagination_base = $wp_rewrite->pagination_base;
        $default_posts_per_page = get_option( 'posts_per_page' );

        foreach ( $post_types as $post_type ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            $post_type_total = $wpdb->get_var(
                $wpdb->prepare(
                    'SELECT COUNT(*) FROM %i WHERE post_status = %s AND post_type = %s',
                    $wpdb->posts,
                    'publish',
                    $post_type
                )
            );

            if ( ! $post_type_total ) {
                continue;
            }

            $post_type_obj = get_post_type_object( $post_type );

            if ( ! $post_type_obj ) {
                continue;
            }

            // cast WP's object back to array
            $post_type_labels = (array) $post_type_obj->labels;

            $plural_form = strtolower( (string) $post_type_labels['name'] );

            // skip post type names containing spaces
            if ( str_contains( $plural_form, ' ' ) ) {
                continue;
            }

            $total_pages = ceil( $post_type_total / $default_posts_per_page );

            for ( $page = 1; $page <= $total_pages; $page++ ) {
                // TODO: skipping page pagination here, but is it covered elsewhere?
                if ( $post_type === 'page' ) {
                    continue;
                }

                if ( $post_type === 'post' ) {
                    $post_archive_slug = '';

                    // check if a Posts page has been set in Settings > Reading
                    if ( get_option( 'page_for_posts' ) !== '0' ) {

                        // get FQURL to Posts Page
                        $post_archive_link = get_post_type_archive_link( 'post' );

                        if ( $post_archive_link ) {
                            $post_archive_slug = str_replace(
                                $wp_site_url,
                                '',
                                trailingslashit( $post_archive_link )
                            );
                        }
                    }

                    yield new PathInfo( "/{$post_archive_slug}{$pagination_base}/{$page}/" );
                } else {
                    yield new PathInfo( "/{$plural_form}/{$pagination_base}/{$page}/" );
                }
            }
        }
    }
}
