<?php
/**
 * Handles URL list functionality for health issues.
 */

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

class Rank_URL_List {

    /**
     * Initialize hooks.
     */
    public static function init() {
        add_action('wp_ajax_rank_get_issue_urls', array(__CLASS__, 'ajax_get_issue_urls'));
    }

    /**
     * AJAX handler for getting URLs from a batch.
     */
    public static function ajax_get_issue_urls() {
        // Verify nonce and permissions
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'rank_ajax_nonce')) {
            wp_send_json_error(array('message' => 'Security check failed'));
            return;
        }

        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => 'Permission denied'));
            return;
        }

        // Get and validate batch ID
        $batch_id = isset($_POST['batch_id']) ? sanitize_key($_POST['batch_id']) : '';
        if (empty($batch_id) || strpos($batch_id, 'rank_batch_') !== 0) {
            wp_send_json_error(array('message' => 'Invalid batch ID'));
            return;
        }

        // Get page and per_page parameters
        $page = isset($_POST['page']) ? max(1, intval($_POST['page'])) : 1;
        $per_page = isset($_POST['per_page']) ? min(200, max(1, intval($_POST['per_page']))) : 200;

        // Which list to show: the issues still to fix ('issues', default), the
        // ones detected as already fixed ('already_fixed'), or unsupported
        // page builders filtered before AI processing ('unsupported').
        $source = isset($_POST['source']) ? sanitize_key($_POST['source']) : 'issues';
        $source_key = 'issues';
        if ( $source === 'already_fixed' ) {
            $source_key = 'already_fixed_issues';
        } elseif ( $source === 'unsupported' ) {
            $source_key = 'unsupported_issues';
        }

        // Get batch data
        $batch_data = get_option($batch_id);
        if (!$batch_data || !isset($batch_data[$source_key]) || !is_array($batch_data[$source_key])) {
            wp_send_json_error(array('message' => 'Batch data not found or invalid'));
            return;
        }
        $issue_type    = isset( $batch_data['issue_type'] ) ? $batch_data['issue_type'] : '';
        $detail_column = self::get_detail_column( $source, $issue_type );

        // Extract URLs from the requested list
        $urls = array();
        foreach ($batch_data[$source_key] as $issue) {
            // Image-optimize groups (built by ajax_filter_already_fixed):
            // one entry per unique image with all pages in page_urls[]. We
            // emit a single row per group, carrying page_urls through so the
            // modal can show "+ N more pages".
            if ( is_array( $issue ) && ! empty( $issue['is_image_group'] ) && ! empty( $issue['page_urls'] ) ) {
                $image_url = isset( $issue['image_url'] ) ? (string) $issue['image_url'] : '';
                $page_urls = array_values( array_unique( array_filter( array_map( 'strval', (array) $issue['page_urls'] ) ) ) );
                if ( empty( $page_urls ) ) {
                    continue;
                }
                $urls[] = array(
                    'url'       => $page_urls[0],
                    'rank_id'   => isset( $issue['rank_id'] ) ? $issue['rank_id'] : '',
                    'title'     => isset( $issue['title'] ) ? $issue['title'] : basename( $page_urls[0] ),
                    'image_url' => $image_url,
                    'detail'    => $image_url,
                    'page_urls' => $page_urls,
                    'is_group'  => true,
                );
                continue;
            }

            $page_url = '';

            // Extract page URL based on issue structure
            if (isset($issue['page']['path_full'])) {
                $page_url = $issue['page']['path_full'];
            } elseif (isset($issue['page']['url'])) {
                $page_url = $issue['page']['url'];
            } elseif (isset($issue['url'])) {
                $page_url = $issue['url'];
            }

            if (!empty($page_url)) {
                // For image-type issues, surface the image URL so the modal can
                // show *why* a page URL appears multiple times (different large
                // images on the same page, or the same image on many pages).
                $image_url = '';
                if (!empty($issue['issue_identifier']) && filter_var($issue['issue_identifier'], FILTER_VALIDATE_URL)) {
                    $image_url = $issue['issue_identifier'];
                } elseif (!empty($issue['parameters']['url']) && filter_var($issue['parameters']['url'], FILTER_VALIDATE_URL)) {
                    $image_url = $issue['parameters']['url'];
                }
                $urls[] = array(
                    'url'       => $page_url,
                    'rank_id'   => isset($issue['rank_id']) ? $issue['rank_id'] : '',
                    'title'     => isset($issue['page']['title']) ? $issue['page']['title'] : basename($page_url),
                    'image_url' => $image_url,
                    'reason'    => ( $source === 'unsupported' && ! empty( $issue['reason'] ) ) ? $issue['reason'] : '',
                    'detail'    => self::get_issue_detail( $issue, $source, $issue_type, $detail_column ),
                );
            }
        }

        // Calculate pagination
        $total = count($urls);
        $total_pages = ceil($total / $per_page);
        $offset = ($page - 1) * $per_page;
        $page_urls = array_slice($urls, $offset, $per_page);

        // Send response
        wp_send_json_success(array(
            'urls' => $page_urls,
            'detail_column' => $detail_column,
            'total' => $total,
            'total_pages' => $total_pages,
            'current_page' => $page
        ));
    }

    /**
     * Describe the optional per-item column for a batch's health-check type.
     *
     * Most checks are page-level and intentionally return no extra column.
     */
    private static function get_detail_column( $source, $issue_type ) {
        if ( $source === 'unsupported' ) {
            return array( 'label' => 'Reason', 'format' => 'text' );
        }
        if ( $issue_type === 'long_h1_h2_tag' ) {
            return array( 'label' => 'Heading', 'format' => 'text' );
        }

        $config = function_exists( 'rank_get_issue_type_config' )
            ? rank_get_issue_type_config( $issue_type )
            : null;
        if ( ! is_array( $config ) || empty( $config['identifier_is_url'] ) ) {
            return null;
        }
        if ( $issue_type === 'missing_alt_tags' || ( $config['content_type'] ?? '' ) === 'image' ) {
            return array( 'label' => 'Image URL', 'format' => 'url' );
        }
        if ( ( $config['content_type'] ?? '' ) === 'url' ) {
            return array( 'label' => 'Broken link URL', 'format' => 'url' );
        }

        return null;
    }

    /**
     * Extract the contextual value described by get_detail_column().
     */
    private static function get_issue_detail( $issue, $source, $issue_type, $detail_column ) {
        if ( empty( $detail_column ) || ! is_array( $issue ) ) {
            return '';
        }
        if ( $source === 'unsupported' ) {
            return isset( $issue['reason'] ) ? (string) $issue['reason'] : '';
        }
        if ( $issue_type === 'long_h1_h2_tag' ) {
            $heading = isset( $issue['issue_identifier'] ) ? (string) $issue['issue_identifier'] : '';
            if ( $heading === '' && isset( $issue['parameters']['tag'] ) ) {
                $heading = (string) $issue['parameters']['tag'];
            }
            if ( $heading === '' ) {
                return '';
            }
            $type = isset( $issue['parameters']['type'] ) ? strtolower( (string) $issue['parameters']['type'] ) : 'h1';
            return in_array( $type, array( 'h1', 'h2' ), true ) ? strtoupper( $type ) . ': ' . $heading : $heading;
        }

        $candidates = array(
            $issue['issue_identifier'] ?? '',
            $issue['parameters']['uri'] ?? '',
            $issue['parameters']['url'] ?? '',
        );
        foreach ( $candidates as $candidate ) {
            if ( is_string( $candidate ) && filter_var( $candidate, FILTER_VALIDATE_URL ) ) {
                return $candidate;
            }
        }

        return '';
    }
}