<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Helper: Busca e processa itens dos feeds RSS
 * Função principal: newssync_get_feed_items($atts)
 */

 // Ensure server-vars helper is loaded early when this file is required directly.
if ( ! function_exists( 'newssync_get_cache_duration' ) ) {
    $newssync_sv = __DIR__ . '/server-vars.php';
    if ( file_exists( $newssync_sv ) ) {
        require_once $newssync_sv;
    }
}

// Helper: determine if a cache-clear bypass was explicitly requested.
if ( ! function_exists( 'newssync_is_cache_clear_request' ) ) {
    function newssync_is_cache_clear_request() {
        if ( ! isset( $_GET['newssync_clear_cache'] ) ) {
            return false;
        }

        // If a nonce is present, verify it explicitly.
        $raw_nonce = filter_input( INPUT_GET, '_wpnonce', FILTER_UNSAFE_RAW );
        if ( $raw_nonce === null ) {
            $raw_nonce = filter_input( INPUT_POST, '_wpnonce', FILTER_UNSAFE_RAW );
        }
        if ( $raw_nonce !== null && $raw_nonce !== false && $raw_nonce !== '' ) {
            $newssync_nonce = wp_unslash( $raw_nonce );
            $newssync_nonce = sanitize_text_field( $newssync_nonce );
            return (bool) wp_verify_nonce( $newssync_nonce, 'newssync_clear_cache_action' );
        }

        // Fallback: allow only authenticated users with manage_options capability.
        return is_user_logged_in() && current_user_can( 'manage_options' );
    }
}

// === CARREGA TODAS AS FUNÇÕES NECESSÁRIAS ===
if ( ! function_exists( 'wp_handle_sideload' ) ) {
    // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Local variable, not global
    $news_file_inc = ABSPATH . 'wp-admin/includes/file.php';
    if ( file_exists( $news_file_inc ) ) {
        require_once $news_file_inc;
    }
}
if ( ! function_exists( 'media_handle_sideload' ) ) {
    // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Local variable, not global
    $news_media_inc = ABSPATH . 'wp-admin/includes/media.php';
    if ( file_exists( $news_media_inc ) ) {
        require_once $news_media_inc;
    }
}
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
    // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Local variable, not global
    $news_image_inc = ABSPATH . 'wp-admin/includes/image.php';
    if ( file_exists( $news_image_inc ) ) {
        require_once $news_image_inc;
    }
}

// === DEBUG HELPER (mantido para uso explícito, sem logs automáticos) ===
if ( ! function_exists( 'newssync_is_debug_mode' ) ) {
    function newssync_is_debug_mode() {
        static $debug = null;
        if ( $debug === null ) {
            $debug = (bool) get_option( 'newssync_debug_mode', false );
        }
        return $debug;
    }
}

/**
 * Faz fetch do feed com tratamento de erro.
 */
function newssync_fetch_feed( $feed_url ) {
    if ( ! function_exists( 'fetch_feed' ) ) {
        $feed_file = ABSPATH . WPINC . '/feed.php';
        if ( file_exists( $feed_file ) ) {
            require_once $feed_file;
        } else {
            return new WP_Error( 'feed_unavailable', __( 'Feed functions not available', 'rss-newssync' ) );
        }
    }

    $rss = fetch_feed( $feed_url );
    if ( is_wp_error( $rss ) ) {
        return $rss;
    }
    return $rss;
}

/**
 * Parse items a partir do objeto SimplePie
 */
function newssync_parse_items( $rss, $category, $feed_url ) {
    if ( is_wp_error( $rss ) || ! $rss->get_item_quantity() ) {
        return [];
    }

    // ✅ NOVO: Extrair metadados do feed (channel/site)
    $feed_title = '';
    $feed_link  = '';

    if ( method_exists( $rss, 'get_title' ) ) {
        $feed_title = $rss->get_title();
    }

    if ( method_exists( $rss, 'get_link' ) ) {
        $feed_link = $rss->get_link();
    }

    // ✅ NOVO: Limpar título do feed (remover subtítulos e descrições)
    if ( ! empty( $feed_title ) ) {
        // Remover tudo após separadores comuns (: | - •)
        $feed_title = preg_split( '/[\:\|\-\•\–\—]/', $feed_title, 2 )[0];

        // Remover extensões e palavras genéricas (.com, News, RSS, etc.)
        $feed_title = preg_replace( '/\.(com|net|org|io|co)\s*(News|RSS|Feed|Blog)?/i', '', $feed_title );

        // Limpar espaços e limitar a 50 caracteres
        $feed_title = trim( $feed_title );
        if ( strlen( $feed_title ) > 50 ) {
            $feed_title = substr( $feed_title, 0, 50 );
        }
    }

    // ✅ NOVO: Fallbacks se título estiver vazio
    if ( empty( $feed_title ) ) {
        $parsed = wp_parse_url( $feed_url );
        if ( ! empty( $parsed['host'] ) ) {
            // Remover "www." e converter para Title Case
            $feed_title = str_replace( 'www.', '', $parsed['host'] );
            $feed_title = ucwords( str_replace( array( '.', '-', '_' ), ' ', $feed_title ) );
        } else {
            $feed_title = __( 'Unknown Source', 'rss-newssync' );
        }
    }

    // ✅ NOVO: Fallback para link
    if ( empty( $feed_link ) ) {
        $parsed = wp_parse_url( $feed_url );
        if ( ! empty( $parsed['scheme'] ) && ! empty( $parsed['host'] ) ) {
            $feed_link = $parsed['scheme'] . '://' . $parsed['host'];
        } else {
            $feed_link = $feed_url;
        }
    }


    $items = [];
    $newssync_items = $rss->get_items( 0, 50 ) ?: [];

    foreach ( $newssync_items as $newssync_item ) {
        // ✅ NOVO: passar metadados do feed
        $processed = newssync_process_item( $newssync_item, $category, $feed_url, $feed_title, $feed_link );
        if ( ! empty( $processed ) ) {
            $items[] = $processed;
        }
    }

    return $items;
}

function newssync_process_item( $newssync_item, $category, $feed_url, $feed_title = '', $feed_link = '' ) {
    if ( ! $newssync_item ) {
        return [];
    }

    $title = $newssync_item->get_title();
    $title = $title !== null ? wp_trim_words( wp_strip_all_tags( $title ), 60, '...' ) : '';
    if ( empty( $title ) ) {
        return [];
    }

    $link = esc_url_raw( $newssync_item->get_permalink() );
    $content = $newssync_item->get_content() ?: $newssync_item->get_description();

    // ✅ NOVO: Tentar extrair autor do item (opcional)
    $author = '';
    if ( method_exists( $newssync_item, 'get_author' ) ) {
        $author_obj = $newssync_item->get_author();
        if ( $author_obj && method_exists( $author_obj, 'get_name' ) ) {
            $author = $author_obj->get_name();

            // Limpar author: remover nome do site se aparecer antes de "by"
            // Ex: "Cointelegraph by Turner Wright" → "Turner Wright"
            if ( strpos( $author, ' by ' ) !== false ) {
                $parts = explode( ' by ', $author, 2 );
                $author = trim( $parts[1] ); // Pegar só o nome após "by"
            }
        }
    }

    $img_url = '';
    if ( function_exists( 'newssync_extract_item_image' ) ) {
        $img_url = newssync_extract_item_image( $newssync_item, $content, $feed_url );
    }

    // RAW dates from SimplePie (preserve original string where possible)
    $date_raw_original = $newssync_item->get_date();
    $date_raw_iso      = $newssync_item->get_date( 'c' );
    // Prefer ISO if present for robust parsing later
    $date_raw = ! empty( $date_raw_iso ) ? $date_raw_iso : $date_raw_original;

    // timestamp UTC if available from SimplePie
    $date_ts = 0;
    try {
        $raw_ts = $newssync_item->get_date( 'U' );
        if ( $raw_ts !== null && $raw_ts !== false && $raw_ts !== '' ) {
            $date_ts = (int) $raw_ts; // this is UTC timestamp
        }
    } catch ( Exception $e ) {}

    // For display, we want a localized human-readable date
    $date_formatted = '';
    if ( ! empty( $date_ts ) ) {
        $local_ts = $date_ts + (int) get_option( 'gmt_offset', 0 ) * 3600;
        $date_formatted = date_i18n( 'd/m/Y H:i', $local_ts );
    } else {
        // Try parsing the raw date string directly (prefer robust parsing via known formats)
        $raw_try = $date_raw ?: ( $date_raw_original ?: '' );
        if ( ! empty( $raw_try ) ) {
            $parsed_ts = false;
            $formats = [
                'Y-m-d\TH:i:sP',
                'Y-m-d\TH:i:s',
                'Y-m-d H:i:s',
                'd/m/Y H:i',
                'm/d/Y H:i',
                'F j, Y g:i a',
            ];
            foreach ( $formats as $f ) {
                $dt = DateTime::createFromFormat( $f, $raw_try );
                if ( $dt !== false ) {
                    $parsed_ts = $dt->getTimestamp();
                    break;
                }
            }
            if ( $parsed_ts === false ) {
                if ( strpos( $raw_try, 'T' ) !== false || preg_match( '/\+\d{2}:?\d{2}|Z$/', $raw_try ) ) {
                    $ts = strtotime( $raw_try );
                    if ( $ts !== false ) {
                        $parsed_ts = $ts;
                    }
                } else {
                    $s = trim( $raw_try );
                    if ( preg_match( '/^\s*(\d{1,2}:\d{2})\s*[-–]\s*(\d{1,2})[\/\-](\d{1,2})(?:[\/\-](\d{2,4}))?\s*$/', $s, $m ) ) {
                        $time_part = $m[1];
                        $day = str_pad( $m[2], 2, '0', STR_PAD_LEFT );
                        $month = str_pad( $m[3], 2, '0', STR_PAD_LEFT );
                        $year = ! empty( $m[4] ) ? $m[4] : gmdate( 'Y' );
                        if ( strlen( $year ) === 2 ) {
                            $year = '20' . $year;
                        }
                        $norm = sprintf( '%02d/%02d/%04d %s', $day, $month, $year, $time_part );
                        $dt = DateTime::createFromFormat( 'd/m/Y H:i', $norm );
                        if ( $dt !== false ) {
                            $parsed_ts = $dt->getTimestamp();
                        }
                    }
                    if ( $parsed_ts === false ) {
                        $ts = strtotime( $raw_try );
                        if ( $ts !== false ) {
                            $parsed_ts = $ts;
                        }
                    }
                }
            }

            if ( $parsed_ts !== false ) {
                $date_ts = (int) $parsed_ts;
                $local_ts = $date_ts + (int) get_option( 'gmt_offset', 0 ) * 3600;
                $date_formatted = date_i18n( 'd/m/Y H:i', $local_ts );
            } else {
                $date_formatted = $raw_try;
            }
        }
    }



    return [
        'title'          => esc_html( $title ),
        'link'           => $link,
        'date'           => $date_formatted,
        'date_raw'       => $date_raw ?? '',
        'date_timestamp' => (int) $date_ts,
        'desc_raw'       => wp_strip_all_tags( $content ),
        'desc'           => wp_strip_all_tags( $content ),
        'img_url'        => $img_url ?: false,
        'category'       => sanitize_text_field( $category ), // ✅ MANTIDO: para filtros internos
        'feed_id'        => md5( $feed_url ),
        'guid'           => $newssync_item->get_id() ?: $link,
        // ✅ NOVO: Metadados do site de origem
        'source_name'    => ! empty( $feed_title ) ? esc_html( $feed_title ) : '',
        'source_url'     => ! empty( $feed_link ) ? esc_url( $feed_link ) : '',
        'author'         => ! empty( $author ) ? esc_html( $author ) : '',
    ];
}

/**
 * Extrai imagem de enclosure/media/or HTML
 */
function newssync_extract_item_image( $newssync_item, $content, $feed_url ) {
    $img_url = false;

    // 1. Enclosure
    $enclosure = method_exists( $newssync_item, 'get_enclosure' ) ? $newssync_item->get_enclosure() : null;
    if ( $enclosure && method_exists( $enclosure, 'get_link' ) ) {
        $enc_link = $enclosure->get_link();
        $type = method_exists( $enclosure, 'get_type' ) ? $enclosure->get_type() : null;
        if ( $enc_link && ( $type === null || stripos( $type, 'image' ) !== false ) ) {
            $img_url = $enc_link;
            if ( strpos( $img_url, 'img.decrypt.co' ) !== false ) {
                if ( preg_match( '#plain/([^&]+)#i', $img_url, $m ) ) {
                    $img_url = htmlspecialchars_decode( $m[1] );
                    $img_url = preg_replace( '/@\w+$/', '', $img_url );
                }
            }
        }
    }

    // 2. Media Content
    if ( ! $img_url && defined( 'SIMPLEPIE_NAMESPACE_MEDIARSS' ) ) {
        $media = $newssync_item->get_item_tags( SIMPLEPIE_NAMESPACE_MEDIARSS, 'content' );
        if ( ! empty( $media[0]['attribs']['']['url'] ) ) {
            $img_url = $media[0]['attribs']['']['url'];
        }
    }

    // 3. Thumbnail
    if ( ! $img_url && defined( 'SIMPLEPIE_NAMESPACE_MEDIARSS' ) ) {
        $thumb = $newssync_item->get_item_tags( SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail' );
        if ( ! empty( $thumb[0]['attribs']['']['url'] ) ) {
            $img_url = $thumb[0]['attribs']['']['url'];
        }
    }

    // 4. HTML extract
    if ( ! $img_url && $content ) {
        $img_url = newssync_extract_image_from_html( $content, $feed_url );
    }

    if ( $img_url ) {
        $img_url = newssync_resolve_url( $img_url, $feed_url );
    }

    return $img_url ?: false;
}

/**
 * Busca itens SEM baixar imagens — retorna array ordenado por data
 */
function newssync_get_feed_items_raw( $atts ) {
    $feeds = (array) get_option( 'newssync_feeds', [] );
    if ( empty( $feeds ) ) {
        return [];
    }

    $all_items = [];

    foreach ( $feeds as $feed ) {
        // Case-insensitive category filter
        if ( ! empty( $atts['category'] ) ) {
            if ( ! isset( $feed['category'] ) || strcasecmp( $feed['category'], $atts['category'] ) !== 0 ) {
                continue;
            }
        }

        $transient_key = 'newssync_feed_raw_' . md5( $feed['url'] );
        $items = get_transient( $transient_key );
        if ( false === $items || newssync_is_cache_clear_request() ) {
            $rss = newssync_fetch_feed( $feed['url'] );
            if ( is_wp_error( $rss ) ) {
                continue;
            }
            $items = newssync_parse_items( $rss, $feed['category'] ?? '', $feed['url'] );
            if ( ! empty( $items ) ) {
                $cache_ttl = ! empty( $atts['cache_ttl'] ) ? $atts['cache_ttl'] : '';
                set_transient( $transient_key, $items, newssync_get_cache_duration( $cache_ttl ) );
            } else {
                $items = [];
            }
        }

        if ( ! is_array( $items ) ) {
            $items = [];
        }
        foreach ( $items as $item ) {
            $item['fetch_order'] = microtime( true );
            $all_items[] = $item;
        }
    }

    // Ordenação por timestamp robusta
    usort( $all_items, function ( $a, $b ) {
        $time_a = 0;
        $time_b = 0;

        if ( ! empty( $a['date_timestamp'] ) ) {
            $time_a = (int) $a['date_timestamp'];
        } elseif ( ! empty( $a['timestamp'] ) ) {
            $time_a = (int) $a['timestamp'];
        } elseif ( ! empty( $a['date_raw'] ) ) {
            $ts = newssync_format_item_date( $a['date_raw'], 'U' );
            $time_a = $ts ? (int) $ts : 0;
        } elseif ( ! empty( $a['date'] ) ) {
            $ts = strtotime( $a['date'] );
            $time_a = $ts ? $ts : 0;
        }

        if ( ! empty( $b['date_timestamp'] ) ) {
            $time_b = (int) $b['date_timestamp'];
        } elseif ( ! empty( $b['timestamp'] ) ) {
            $time_b = (int) $b['timestamp'];
        } elseif ( ! empty( $b['date_raw'] ) ) {
            $ts = newssync_format_item_date( $b['date_raw'], 'U' );
            $time_b = $ts ? (int) $ts : 0;
        } elseif ( ! empty( $b['date'] ) ) {
            $ts = strtotime( $b['date'] );
            $time_b = $ts ? $ts : 0;
        }

        if ( $time_a === $time_b ) {
            return ( $b['fetch_order'] ?? 0 ) <=> ( $a['fetch_order'] ?? 0 );
        }

        return $time_b <=> $time_a;
    } );

    return $all_items;
}

/**
 * Função principal chamada pelo shortcode
 */
function newssync_get_feed_items( $atts ) {
    $feeds = (array) get_option( 'newssync_feeds', [] );
    if ( empty( $feeds ) ) {
        return [];
    }

    $all_items = [];
    $cache_ttl = ! empty( $atts['cache_ttl'] ) ? $atts['cache_ttl'] : '';

    foreach ( $feeds as $feed ) {
        // Case-insensitive category filter
        if ( ! empty( $atts['category'] ) ) {
            if ( ! isset( $feed['category'] ) || strcasecmp( $feed['category'], $atts['category'] ) !== 0 ) {
                continue;
            }
        }

        $items = newssync_fetch_feed_items( $feed['url'], $feed['category'] ?? '', $cache_ttl );

        if ( ! is_array( $items ) ) {
            $items = [];
        }

        if ( ! empty( $atts['category'] ) && isset( $atts['limit'] ) && is_numeric( $atts['limit'] ) ) {
            $items = array_slice( $items, 0, intval( $atts['limit'] ) );
        }

        foreach ( $items as &$it ) {
            if ( ! isset( $it['fetch_order'] ) ) {
                $it['fetch_order'] = microtime( true );
            }
            if ( ! empty( $it['date_timestamp'] ) ) {
                $it['timestamp'] = (int) $it['date_timestamp']; // UTC
            } else {
                $raw = $it['date_raw'] ?? ( $it['date'] ?? '' );
                $ts = newssync_format_item_date( $raw, 'U' );
                $it['timestamp'] = $ts ? (int) $ts : 0;
            }
        }
        unset( $it );

        $all_items = array_merge( $all_items, $items );
    }

    // Ordenar globalmente por timestamp (mais recentes primeiro).
    usort( $all_items, function ( $a, $b ) {
        $ta = isset( $a['timestamp'] ) ? (int) $a['timestamp'] : 0;
        $tb = isset( $b['timestamp'] ) ? (int) $b['timestamp'] : 0;

        if ( $ta === $tb ) {
            return ( $b['fetch_order'] ?? 0 ) <=> ( $a['fetch_order'] ?? 0 );
        }
        return $tb <=> $ta;
    } );

    // Remover duplicados (mantendo a primeira ocorrência)
    $all_items = newssync_remove_repeated_posts( $all_items );

    // Aplicar limite global quando apropriado
    if ( empty( $atts['category'] ) && isset( $atts['limit'] ) && is_numeric( $atts['limit'] ) ) {
        $all_items = array_slice( $all_items, 0, intval( $atts['limit'] ) );
    }

    return $all_items;
}

/**
 * Fetch com cache
 */
function newssync_fetch_feed_items( $feed_url, $category, $cache_ttl = '' ) {
    $transient_key = 'newssync_feed_' . md5( $feed_url );
    $items = get_transient( $transient_key );

    if ( false === $items || newssync_is_cache_clear_request() ) {
        $items = newssync_parse_feed( $feed_url, $category );
        if ( ! is_array( $items ) ) {
            $items = [];
        }
        set_transient( $transient_key, $items, newssync_get_cache_duration( $cache_ttl ) );
    }

    return $items;
}


/**
 * Faz o fetch e parse do RSS (simplificado)
 */
function newssync_parse_feed( $feed_url, $category ) {
    if ( ! function_exists( 'fetch_feed' ) ) {
        $feed_file = ABSPATH . WPINC . '/feed.php';
        if ( file_exists( $feed_file ) ) {
            require_once $feed_file;
        } else {
            return array();
        }
    }

    $rss = fetch_feed( $feed_url );
    if ( is_wp_error( $rss ) ) {
        return [];
    }

    // ✅ NOVO: Extrair metadados do feed
    $feed_title = '';
    $feed_link  = '';

    if ( method_exists( $rss, 'get_title' ) ) {
        $feed_title = $rss->get_title();
    }

    if ( method_exists( $rss, 'get_link' ) ) {
        $feed_link = $rss->get_link();
    }

    // ✅ NOVO: Limpar título do feed (remover subtítulos e descrições)
    if ( ! empty( $feed_title ) ) {
        // Remover tudo após separadores comuns (: | - •)
        $feed_title = preg_split( '/[\:\|\-\•\–\—]/', $feed_title, 2 )[0];
        // Limpar espaços e limitar a 50 caracteres
        $feed_title = trim( $feed_title );
        if ( strlen( $feed_title ) > 50 ) {
            $feed_title = substr( $feed_title, 0, 50 );
        }
    }

    // ✅ NOVO: Fallbacks
    if ( empty( $feed_title ) ) {
        $parsed = wp_parse_url( $feed_url );
        if ( ! empty( $parsed['host'] ) ) {
            $feed_title = str_replace( 'www.', '', $parsed['host'] );
            $feed_title = ucwords( str_replace( array( '.', '-', '_' ), ' ', $feed_title ) );
        } else {
            $feed_title = __( 'Unknown Source', 'rss-newssync' );
        }
    }

    if ( empty( $feed_link ) ) {
        $parsed = wp_parse_url( $feed_url );
        if ( ! empty( $parsed['scheme'] ) && ! empty( $parsed['host'] ) ) {
            $feed_link = $parsed['scheme'] . '://' . $parsed['host'];
        } else {
            $feed_link = $feed_url;
        }
    }

    $items = [];
    $newssync_items = $rss->get_items( 0, 50 ) ?: [];

    foreach ( $newssync_items as $newssync_item ) {
        // ✅ NOVO: passar metadados do feed
        $items[] = newssync_process_item( $newssync_item, $category, $feed_url, $feed_title, $feed_link );
    }

    return $items;
}

/**
 * Extrai imagem de HTML
 */
function newssync_extract_image_from_html( $html, $feed_url ) {
    if ( ! $html ) {
        return false;
    }

    $html = preg_replace( '/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html );
    $html = preg_replace( '/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $html );

    if ( strpos( $feed_url, 'decrypt.co' ) !== false ) {
        if ( preg_match( '#img\.decrypt\.co/insecure/[^/]+/plain/([^"\']+)#i', $html, $m ) ) {
            $inner_url = $m[1];
            $inner_url = preg_replace( '/@\w+$/', '', $inner_url );
            return newssync_resolve_url( $inner_url, $feed_url );
        }
    }

    $patterns = [
        '/<img[^>]+src=[\'"]([^\'"]+)[\'"]/i',
        '/<img[^>]+data-src=[\'"]([^\'"]+)[\'"]/i',
        '/<img[^>]+data-lazy-src=[\'"]([^\'"]+)[\'"]/i',
        '/<img[^>]+srcset=[\'"]([^\'"]+)[\'"]/i',
    ];

    foreach ( $patterns as $pattern ) {
        if ( preg_match( $pattern, $html, $m ) ) {
            $url = $m[1];
            if ( strpos( $url, ',' ) !== false ) {
                $url = trim( explode( ',', $url )[0] );
                $url = preg_replace( '/\s+\d+w$/', '', $url );
            }
            return newssync_resolve_url( $url, $feed_url );
        }
    }

    if ( preg_match( '/<figure[^>]*>.*?<img[^>]+src=[\'"]([^\'"]+)[\'"]/is', $html, $m ) ) {
        return newssync_resolve_url( $m[1], $feed_url );
    }

    return false;
}

/**
 * Resolve URL relativa
 */
function newssync_resolve_url( $url, $feed_url ) {
    if ( ! $url ) {
        return $url;
    }
    if ( preg_match( '#^https?://#i', $url ) ) {
        return $url;
    }

    $base = preg_replace( '#/[^/]*$#', '/', $feed_url );
    return rtrim( $base, '/' ) . '/' . ltrim( $url, '/' );
}

/**
 * Baixa imagem e salva no Media Library
 */
function newssync_get_image_url( $img_url, $category = 'geral' ) {
    if ( ! $img_url || ! filter_var( $img_url, FILTER_VALIDATE_URL ) ) {
        return newssync_get_random_placeholder();
    }

    // Try fast lookup by attachment URL first (native WP helper)
    $attach_id = attachment_url_to_postid( $img_url );
    if ( $attach_id ) {
        $url = wp_get_attachment_url( $attach_id );
        if ( $url ) {
            return $url;
        }
    }

    // Next: try lookup by postmeta key _newssync_source_url using $wpdb
    global $wpdb;
    $sql = $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s LIMIT 1", '_newssync_source_url', $img_url );
    // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Query is prepared above, lookup for previously imported image by source URL
    $res = $wpdb->get_var( $sql );
    if ( $res ) {
        $url = wp_get_attachment_url( (int) $res );
        if ( $url ) {
            return $url;
        }
    }

    $file_array = newssync_download_temp_image( $img_url );
    if ( is_wp_error( $file_array ) ) {
        return newssync_get_random_placeholder();
    }

    $attachment_id = media_handle_sideload( $file_array, 0 );
    if ( is_wp_error( $attachment_id ) ) {
        @wp_delete_file( $file_array['tmp_name'] );
        return newssync_get_random_placeholder();
    }

    update_post_meta( $attachment_id, '_newssync_source_url', $img_url );
    @wp_delete_file( $file_array['tmp_name'] );

    $url = wp_get_attachment_url( $attachment_id );
    return $url ?: newssync_get_random_placeholder();
}

/**
 * Download da imagem para tmp
 */
function newssync_download_temp_image( $img_url ) {
    $sslverify = true;
    if ( get_option( 'newssync_disable_ssl_verify', false ) ) {
        $sslverify = false;
    }

    $response = wp_remote_get( $img_url, [
        'timeout' => 15,
        'headers' => [
            'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
            'Accept'     => 'image/webp,image/apng,image/*,*/*;q=0.8',
        ],
        'sslverify' => $sslverify,
    ] );

    if ( is_wp_error( $response ) ) {
        return $response;
    }

    $code = wp_remote_retrieve_response_code( $response );
    if ( $code !== 200 ) {
        return new WP_Error( 'http_error', "HTTP $code" );
    }

    $body = wp_remote_retrieve_body( $response );
    if ( strlen( $body ) < 512 ) {
        return new WP_Error( 'small_file', 'Imagem muito pequena' );
    }

    $upload_dir = wp_upload_dir();
    $tmp_dir = $upload_dir['basedir'] . '/tmp-rss-images';
    if ( ! file_exists( $tmp_dir ) ) {
        wp_mkdir_p( $tmp_dir );
    }

    $tmp = $tmp_dir . '/newssync_temp_' . uniqid() . '.tmp';
    file_put_contents( $tmp, $body );

    $filename = sanitize_file_name( pathinfo( wp_parse_url( $img_url, PHP_URL_PATH ), PATHINFO_BASENAME ) );
    $filename = $filename ?: 'image-' . md5( $img_url ) . '.jpg';

    return [
        'tmp_name' => $tmp,
        'name'     => $filename,
        'type'     => wp_remote_retrieve_header( $response, 'content-type' ) ?: 'image/jpeg',
    ];
}

/**
 * Placeholder aleatório com memória
 */
function newssync_get_random_placeholder() {
    $dir = NEWSSYNC_PLUGIN_DIR . 'includes/assets/images/placeholders/';
    $url = NEWSSYNC_PLUGIN_URL . 'includes/assets/images/placeholders/';
    $files = glob( $dir . '*.{jpg,jpeg,png,webp,gif}', GLOB_BRACE );

    if ( empty( $files ) ) {
        return $url . 'default.jpg';
    }

    $client_key_part = '';
    $remote_addr = function_exists( 'newssync_get_server_var' ) ? newssync_get_server_var( 'REMOTE_ADDR' ) : '';
    if ( '' !== $remote_addr ) {
        $remote_addr = filter_var( $remote_addr, FILTER_VALIDATE_IP ) ? $remote_addr : '';
        if ( '' !== $remote_addr ) {
            $client_key_part .= $remote_addr;
        }
    }

    $user_agent = function_exists( 'newssync_get_server_var' ) ? newssync_get_server_var( 'HTTP_USER_AGENT' ) : '';
    if ( '' !== $user_agent ) {
        $client_key_part .= $user_agent;
    }

    if ( $client_key_part === '' ) {
        $client_key_part = uniqid( 'rspph_', true );
    }

    $key = 'newssync_ph_' . substr( md5( $client_key_part ), 0, 12 );
    $history = get_transient( $key );
    if ( ! is_array( $history ) ) {
        $history = [];
    }

    $available = array_filter( $files, function ( $f ) use ( $history ) {
        return ! in_array( basename( $f ), $history, true );
    } );

    if ( empty( $available ) ) {
        $available = $files;
        $history   = [];
    }

    $chosen = $available[ array_rand( $available ) ];
    $filename = basename( $chosen );

    $history[] = $filename;
    if ( count( $history ) > 6 ) {
        array_shift( $history );
    }
    set_transient( $key, $history, DAY_IN_SECONDS );

    return $url . $filename;
}

/**
 * Cache duration helper
 */
function newssync_get_cache_duration() {
    $opt = get_option( 'newssync_cache_duration', '6h' );

    $map = [
        '6h'  => 6 * HOUR_IN_SECONDS,
        '24h' => 24 * HOUR_IN_SECONDS,
    ];

    if ( isset( $map[ $opt ] ) ) {
        return (int) $map[ $opt ];
    }

    return 6 * HOUR_IN_SECONDS;
}

/**
 * Apply global limit helper
 */
function newssync_apply_global_limit( $items, $limit ) {
    if ( $limit && is_numeric( $limit ) ) {
        return array_slice( $items, 0, intval( $limit ) );
    }
    return $items;
}

/**
 * Remove itens duplicados pelo link
 */
function newssync_remove_repeated_posts( $items ) {
    $unique = [];
    $seen   = [];

    foreach ( $items as $item ) {
        $link = $item['link'] ?? '';
        if ( $link && in_array( $link, $seen, true ) ) {
            continue;
        }
        if ( $link ) {
            $seen[] = $link;
        }
        $unique[] = $item;
    }

    return $unique;
}

/**
 * Converte data RSS para timestamp/site format
 */
function newssync_format_item_date( $date_string, $format = 'H:i' ) {
    if ( empty( $date_string ) ) {
        return '';
    }

    $timestamp = false;

    $formats = [
        'Y-m-d\TH:i:sP',
        'Y-m-d\TH:i:s',
        'Y-m-d H:i:s',
        'd/m/Y H:i',
        'm/d/Y H:i',
        'F j, Y g:i a',
    ];

    foreach ( $formats as $f ) {
        $dt = DateTime::createFromFormat( $f, $date_string );
        if ( $dt !== false ) {
            $timestamp = $dt->getTimestamp();
            break;
        }
    }

    if ( $timestamp === false ) {
        $ts = strtotime( $date_string );
        if ( $ts !== false ) {
            $timestamp = $ts;
        }
    }

    if ( $timestamp === false || $timestamp === null ) {
        return '';
    }

    if ( $format === 'U' ) {
        return (string) $timestamp;
    }

    $wp_offset = intval( get_option( 'gmt_offset', 0 ) );
    $local_ts = $timestamp + ( $wp_offset * 3600 );
    return gmdate( $format, $local_ts );
}

/**
 * Normalize timestamp helper
 */
function newssync_normalize_timestamp( &$item ) {
    if ( ! empty( $item['date_timestamp'] ) ) {
        $item['timestamp'] = (int) $item['date_timestamp'];
        $item['timestamp'] = apply_filters( 'newssync_item_timestamp', $item['timestamp'], $item );
        return;
    }

    $raw = $item['date_raw'] ?? ( $item['date'] ?? '' );
    if ( ! empty( $raw ) ) {
        $ts = newssync_format_item_date( $raw, 'U' );
        $item['timestamp'] = $ts ? (int) $ts : 0;
    } else {
        $item['timestamp'] = 0;
    }
    $item['timestamp'] = apply_filters( 'newssync_item_timestamp', $item['timestamp'], $item );
}

/**
 * Get max per feed
 */
function newssync_get_max_per_feed( $atts ) {
    $default = 3;
    if ( ! empty( $atts['category'] ) ) {
        return is_numeric( $atts['limit'] ) ? max( $default, (int) $atts['limit'] ) : $default;
    }
    return apply_filters( 'newssync_max_per_feed', $default, $atts );
}
