<?php

use Stichoza\GoogleTranslate\GoogleTranslate;

class scrapes
{	 	
	private $Go_Curl;

    public function __construct()
    {
        $this->Go_Curl = new Go_Curl();
    }
	
	public function scrape_web_info($url)	{
		require_once get_template_directory() . '/libs/addons/inc/ssl.php';
		@ini_set('user_agent', 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)');

		 
		global $opt_themes;
		 

		if ($opt_themes['bahasa_on']) {
			$tr			= new GoogleTranslate();
			$bahasa			= $opt_themes['bahasa'];
		}

		$url			= $_POST['wp_url'];

		$arr			= array();

		//$links	= scrape_site($url);	
		//$links	= file_get_html($url);
		//$links	= file_get_contents($url, false, stream_context_create($ssl));
		//$links	= $this->Go_Curl->geturl($url);	 

		$status 	= http_response($url); 
 
		if($status === 403) {
			$html	= scrapedo($url); 
		} else {
			$html	= get_url($url);	
		}
		   
		// Asumsikan $html sudah berisi konten halaman dari Go_Curl

		// 1. Ekstrak isi <title> (full title)
		$raw_titles = $this->Go_Curl->match('/<title>(.*?)<\/title>/msi', $html, 1);

		if (empty($raw_titles)) {
			// fallback jika regex gagal
			$raw_titles = '';
		}

		// 2. Cleaning agresif tapi aman
		$raw_titles = str_replace(
			['download', 'Download', 'DOWNLOAD', 'Downloads', 'downloads', 
			 'apk', 'Apk', 'APK', 'Apks', 'APKS', 'MOD', 'mod', 'Mod'],
			'',
			$raw_titles
		);

		$clean_titles = $raw_titles;

		// Hapus prefix "Download " (case insensitive)
		$clean_titles = preg_replace('/^download\s+/i', '', $clean_titles);

		// Hapus suffix " for Android" (case insensitive, termasuk variasi spasi)
		$clean_titles = preg_replace('/\s+for\s+Android$/i', '', $clean_titles);

		// Hapus kata-kata tidak perlu: download, apk, mod, dll.
		
		//$clean_titles = preg_replace('/\b(download|downloads|apk|apks|mod|hack|premium|pro|full|unlimited)\b\s*/i', ' ', $clean_titles);

		// Hapus semua isi dalam kurung beserta kurungnya ((), [], {}, <>)
		$clean_titles = preg_replace('/\s*[\(\[\{<].*?[\)\]\}>]\s*/i', ' ', $clean_titles);

		// Hapus versi angka (1.9.12, v1.0, 2.0.1, dll.)
		$clean_titles = preg_replace('/\b(v?[\d\.\_]+)\b/i', ' ', $clean_titles);

		// Hapus tanda hubung akhir atau garbage lain (misal: " - 5play.org")
		$clean_titles = preg_replace('/\s*[-–—].*$/', '', $clean_titles);

		// Bersihkan spasi berlebih dan trim
		$clean_titles = trim(preg_replace('/\s+/', ' ', $clean_titles));

		// Hasil akhir: $clean_titles siap dipakai untuk search Play Store ID
		 

		$CariJudul 			= $clean_titles; 
		//print_r($CariJudul);
		
		$h1_raw2 = wp_strip_all_tags( $this->Go_Curl->match( '/<h1 class="h2 font-weight-bold"[^>]*>(.*?)<\/h1>/msi', $html, 1 ) );
		/*
		id info
		*/		 
		
		$arr['id_ps']		= $this->Go_Curl->match('/Get it On.*?<a.*?href="(.*?)".*?>/ms', $html, 1);
		$arr['id_ps']		= $this->Go_Curl->validate_gplay_id($arr['id_ps']);

		$arr['title_id']	= $arr['id_ps'];
		$arr['title_id_2']	= $arr['id_ps'];
 		  
		
        $gp_id 				= !empty($arr['id_ps']) ? $arr['id_ps'] : ($arr['title_id'] ?? $arr['title_id_2'] ?? '');
		
		
		if ( !empty($gp_id) ) {			
			$titleId		= $gp_id; 
		} else {			  
			$titleId 		= $this->Go_Curl->get_playstore_id_by_title_google($h1_raw2);
		}
		 
		
		//$titleId 			= $gp_id; 
		$arr['GP_ID'] 		= $titleId; 
		
		if ( !empty($titleId) ) {
			require_once get_template_directory().'/libs/addons/includes/playstore.php';
		}
		 
		// Primary: From page <title> tag – e.g., "App Name vX.X.X MOD APK (Premium Unlocked) Download"
		$title_raw = $this->Go_Curl->match( '/<title>(.*?)<\/title>/msi', $html, 1 );
		$arr['title'] = trim( $title_raw );

		// Secondary: From main <h1> – usually cleaner, e.g., "App Name vX.X.X MOD APK (Premium Unlocked)"
		$h1_raw = wp_strip_all_tags( $this->Go_Curl->match( '/<h1 class="h2 font-weight-bold"[^>]*>(.*?)<\/h1>/msi', $html, 1 ) );
		$arr['title_sc'] = trim( $h1_raw );

		// Use h1 as fallback if <title> is empty or missing
		if ( empty( $arr['title'] ) ) {
			$arr['title'] = $arr['title_sc'];
		}

		// Comprehensive cleaning function (handles current site patterns)
		$clean_title = function( $text ) {
			if ( empty( $text ) ) {
				return '';
			}

			// Decode HTML entities (e.g., &#8211; → –)
			$text = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5 );

			// Remove site-specific and common junk (case-insensitive)
			$unwanted = [
				'liteapks.com', 'LITEAPKS.COM',
				'MOD APK', 'Mod Apk', 'MOD', 'Mod',
				'Premium Unlocked', 'Pro Unlocked', 'Full Version', 'AD-Free',
				'free', 'Free', 'for Android', 'Download', '+'
			];
			$text = str_ireplace( $unwanted, '', $text );

			// Clean common separators around version/MOD
			$text = preg_replace( '/\s*[-–—|•:]\s*/', ' ', $text );

			// Normalize whitespace
			$text = preg_replace( '/\s+/', ' ', $text );

			return trim( $text );
		};

		$arr['title']    = $clean_title( $arr['title'] );
		$arr['title_sc'] = $clean_title( $arr['title_sc'] );

		// Standardize MOD features brackets to [ ] (preserves them nicely)
		$arr['title'] = str_replace( ['(', ')'], ['[', ']'], $arr['title'] );
		$arr['title_sc'] = str_replace( ['(', ')'], ['[', ']'], $arr['title_sc'] );

		// Final stray cleanup
		$arr['title']    = str_ireplace( ' download ', ' ', $arr['title'] );
		$arr['title_sc'] = str_ireplace( ' download ', ' ', $arr['title_sc'] );

		$arr['title']    = trim( $arr['title'] );
		$arr['title_sc'] = trim( $arr['title_sc'] );

		$arr['poster_sc']	= $this->Go_Curl->match('/<meta property="og:image" content="(.*?)" \/>/ms', $html, 1);
		// === Improved App Name Extraction & Cleaning (Robust for various MOD sites) ===

		// Primary: Extract from "App Name" row in info table
		$app_name_raw = wp_strip_all_tags( $this->Go_Curl->match( 
			'/App Name.*?<td[^>]*style="width:\s*55%;?"[^>]*>(.*?)<\/td>/msi', 
			$html, 1 
		) );

		$arr['app_name'] = trim( $app_name_raw );

		// Fallback 1: Broader match if style attribute varies
		if ( empty( $arr['app_name'] ) ) {
			$arr['app_name'] = trim( wp_strip_all_tags( $this->Go_Curl->match( 
				'/App Name.*?<td[^>]*>(.*?)<\/td>/msi', 
				$html, 1 
			) ) );
		}

		// Fallback 2: Use cleaned main title if still empty
		if ( empty( $arr['app_name'] ) && ! empty( $arr['title'] ) ) {
			// Take everything before version number or MOD brackets
			if ( preg_match( '/^([^[\(\d]+?)(?:\s+v|\s*\[|\s*\()/i', $arr['title'], $m ) ) {
				$arr['app_name'] = trim( $m[1] );
			} else {
				$arr['app_name'] = $arr['title'];
			}
		}

		// Comprehensive cleaning
		$arr['app_name'] = html_entity_decode( $arr['app_name'], ENT_QUOTES | ENT_HTML5 );

		$unwanted = [
			'APK', 'Apk', 'apk', 'MOD', 'Mod', 'mod',
			'Premium', 'Pro', 'Unlocked', 'Full',
			'Lite', 'Plus', '+'
		];
		$arr['app_name'] = str_ireplace( $unwanted, '', $arr['app_name'] );

		// Normalize whitespace and separators
		$arr['app_name'] = preg_replace( '/\s*[-–—|•:]\s*/', ' ', $arr['app_name'] );
		$arr['app_name'] = preg_replace( '/\s+/', ' ', $arr['app_name'] );

		$arr['app_name'] = trim( $arr['app_name'] );
		
		// === Improved Version Extraction & Cleaning (Robust for MOD sites) ===

		// Primary: Extract from "Latest Version" row in info table
		$version_raw = wp_strip_all_tags( $this->Go_Curl->match( 
			'/Latest Version.*?<td[^>]*style="width:\s*55%;?"[^>]*>(.*?)<\/td>/msi', 
			$html, 1 
		) );

		$arr['version_sc'] = trim( $version_raw );

		// Fallback 1: Broader match if style or <th> varies
		if ( empty( $arr['version_sc'] ) ) {
			$arr['version_sc'] = trim( wp_strip_all_tags( $this->Go_Curl->match( 
				'/Latest Version.*?<td[^>]*>(.*?)<\/td>/msi', 
				$html, 1 
			) ) );
		}

		// Fallback 2: Extract from title if still empty (very common on MOD sites)
		if ( empty( $arr['version_sc'] ) && ! empty( $arr['title'] ) ) {
			// Look for pattern like "v5.0.277" or "5.0.277" near the end or middle
			if ( preg_match( '/\b(v?[\d][\d\.\w]+)\b/i', $arr['title'], $m ) ) {
				$arr['version_sc'] = $m[1];
			}
		}

		// Clean the version string
		if ( ! empty( $arr['version_sc'] ) ) {
			// Remove leading 'v' or 'V' (case-insensitive)
			$arr['version_sc'] = preg_replace( '/^v/i', '', $arr['version_sc'] );

			// Remove common trailing junk (e.g., "build 123", "(Premium)", etc.)
			$arr['version_sc'] = preg_replace( '/\s*(build|beta|alpha|mod|premium|unlocked).*$/i', '', $arr['version_sc'] );

			// Normalize: keep only numbers, dots, and letters (safe for version formats)
			$arr['version_sc'] = preg_replace( '/[^0-9a-z\.\-]/i', '', $arr['version_sc'] );

			$arr['version_sc'] = trim( $arr['version_sc'] );
		}

		// Final fallback: empty string if nothing found
		$arr['version_sc'] = $arr['version_sc'] ?? '';

		$arr['size_sc']		= wp_strip_all_tags($this->Go_Curl->match('/<th style="width: 45%;">.*?Size.*?<td style="width: 55%;">(.*?)<\/td>/ms', $html, 1));
		$arr['genre_sc']	= wp_strip_all_tags($this->Go_Curl->match('/<th style="width: 45%;">.*?Genre.*?<td style="width: 55%;"><a.*?>(.*?)<\/a><\/td>/ms', $html, 1));
		$arr['developer_sc'] = wp_strip_all_tags($this->Go_Curl->match('/<th style="width: 45%;">.*?Publisher.*?<td style="width: 55%;"><a.*?>(.*?)<\/a><\/td>/ms', $html, 1));
		$arr['updates']		= wp_strip_all_tags($this->Go_Curl->match('/<time class="d-block">.*?<em class="align-middle">(.*?)\(.*?<\/em>/ms', $html, 1));
		$arr['updated_sc'] 	= date("M d, Y", strtotime($arr['updates']));
		// === Improved & Safe MOD Features Extraction from Title ===

		$title_source = $arr['title'] ?? $arr['title_sc'] ?? '';

		// Extract content inside [ ] brackets (most common for MOD features)
		$arr['carimod'] = preg_match( '/\[([^\[\]]*)\]/', $title_source, $matches );

		if ( $arr['carimod'] && isset( $matches[1] ) ) {
			$arr['mods'] = trim( $matches[1] );

			// Clean up the extracted MOD text
			$arr['mods'] = html_entity_decode( $arr['mods'], ENT_QUOTES | ENT_HTML5 );
			$arr['mods'] = preg_replace( '/\s+/', ' ', $arr['mods'] );           // normalize spaces
			$arr['mods'] = trim( $arr['mods'], " ,;|•-–" );                     // remove trailing separators
		} else {
			$arr['mods'] = ''; // No MOD features found
		}

		//$arr['mods_2']	= str_replace(array('getmodsapk.com', 'MOD ', 'Download'), '', $this->Go_Curl->match('/<span class="sm:text-left text-center block w-full">.*?\((.*?)\).*?<\/span>/ms', $html, 1));
		//if ($arr['mods_2'] === FALSE or $arr['mods_2'] == '') $arr['mods_2'] = $arr['mods'];	
		$arr['full_mod_title']		= '';
		
		$arr['full_mod']	= $this->Go_Curl->match('/<div id="accordion-more-info" class="mb-3 accordion accordion-more-info">(.*?)<div class="mb-3">/ms', $html, 1);
		$arr['full_mod'] = $this->clean_full_mod( $arr['full_mod'] ?? '' );

		$arr['article_sc']	= $this->Go_Curl->match('/<div class="mb-3 entry-content">(.*?)<h2 id="download\".*?/ms', $html, 1);
		$arr['article_sc'] = $this->clean_article_sc( $arr['article_sc'] ?? '' );
		$arr['article_content'] = $arr['article_sc']; // if you still need both

		$arr['summary_sc']	= wp_strip_all_tags(mb_substr($arr['article_content'], 0, 100, 'utf8'));
		$arr['canonical']	= '';
		
		$arr['download_links_page']	= $this->Go_Curl->match('/<a class="btn btn-primary btn-block mb-3" href="(.*?)\".*?>/ms', $html, 1);

		/*
		download link
		*/
		// === Improved Download Links Extraction (Robust for current MOD sites – December 2025) ===

		$download_page = $arr['download_links_page'] ?? '';

		if ( ! empty( $download_page ) ) {
			// Fetch download page with proper bypass handling
			$page_status = http_response( $download_page ); // assuming you have this function

			if ( $page_status === 403 ) {
				$download_info = $this->scrapedo( $download_page );
			} else {
				$download_info = get_url( $download_page );
			}

			if ( empty( $download_info ) ) {
				$arr['downloadlinks_gma'] = $arr['name_downloadlinks_gma'] = $arr['size_downloadlinks_gma'] = $arr['notes_downloadlinks_gma'] = $arr['apklink'] = $arr['apkname'] = [];
				$arr['link_apk'] = '';
			} else {
				// Extract the main download variants section
				$section = $this->Go_Curl->match( 
					'/<article[^>]*>(.*?)<div class="small mb-3"/msi', 
					$download_info, 1 
				);

				// Fallback if the ending marker changes
				if ( empty( $section ) ) {
					$section = $this->Go_Curl->match( '/<article[^>]*>(.*?)<\/article>/msi', $download_info, 1 );
				}

				if ( ! empty( $section ) ) {
					// Download links (intermediate pages)
					$arr['downloadlinks_gma'] = $this->Go_Curl->match_all( 
						'/<a class="btn btn-light[^"]*"[^>]*href="(.*?)"/msi', 
						$section, 1 
					);

					// Variant names/titles
					$arr['name_downloadlinks_gma'] = $this->Go_Curl->match_all( 
						'/<[^>]*class="h6 font-weight-semibold[^>]*>(.*?)</msi', 
						$section, 1 
					);
					// Clean extra whitespace in names
					$arr['name_downloadlinks_gma'] = array_map( function( $name ) {
						return preg_replace( '/\s+/', ' ', trim( $name ) );
					}, $arr['name_downloadlinks_gma'] );

					// File sizes
					$arr['size_downloadlinks_gma'] = $this->Go_Curl->match_all( 
						'/<span class="text-muted d-block ml-auto">(.*?)<\/span>/msi', 
						$section, 1 
					);

					// Notes (e.g., "Original APK", "MOD APK", etc.)
					$arr['notes_downloadlinks_gma'] = $this->Go_Curl->match_all( 
						'/<div class="small bg-light p-3">(.*?)<\/div>/msi', 
						$section, 1 
					);
					$arr['notes_downloadlinks_gma'] = array_map( function( $note ) {
						return preg_replace( '/\s+/', ' ', trim( $note ) );
					}, $arr['notes_downloadlinks_gma'] );

					// Types left empty as per your original (or you can populate from notes if needed)
					$arr['types_downloadlinks_gma'] = [];

					// Extract final direct APK links
					$arr['apklink'] = [];
					$arr['apkname'] = [];

					foreach ( $arr['downloadlinks_gma'] as $intermediate_link ) {
						if ( empty( $intermediate_link ) ) {
							$arr['apklink'][] = '';
							$arr['apkname'][] = '';
							continue;
						}

						// Fetch intermediate download page
						$link_status = http_response( $intermediate_link );
						if ( $link_status === 403 ) {
							$intermediate_html = $this->scrapedo( $intermediate_link );
						} else {
							$intermediate_html = get_url( $intermediate_link );
						}

						// Extract final download URL (data-href on the real button)
						$final_link = $this->Go_Curl->match( 
							'/<a id="download-loaded-link"[^>]*data-href="(.*?)"/msi', 
							$intermediate_html, 1 
						);

						// Fallback: direct href if data-href not present
						if ( empty( $final_link ) ) {
							$final_link = $this->Go_Curl->match( '/<a[^>]*class="[^"]*download[^"]*"[^>]*href="(.*?)"/msi', $intermediate_html, 1 );
						}

						$arr['apklink'][] = $final_link ?: $intermediate_link;

						// Extract variant-specific name (e.g., "MOD APK", "Original")
						$variant_name = $this->Go_Curl->match( 
							'/<h1 class="h5 font-weight-semibold mb-3">(.*?)<\/h1>/msi', 
							$intermediate_html, 1 
						);
						$arr['apkname'][] = trim( $variant_name );
					}

					// Primary download link (usually first one = main MOD)
					$arr['link_apk'] = $arr['apklink'][0] ?? '';
				} else {
					// No section found
					$arr['downloadlinks_gma'] = $arr['name_downloadlinks_gma'] = $arr['size_downloadlinks_gma'] = $arr['notes_downloadlinks_gma'] = $arr['apklink'] = $arr['apkname'] = [];
					$arr['link_apk'] = '';
				}
			}
		} else {
			// No download page URL
			$arr['downloadlinks_gma'] = $arr['name_downloadlinks_gma'] = $arr['size_downloadlinks_gma'] = $arr['notes_downloadlinks_gma'] = $arr['apklink'] = $arr['apkname'] = [];
			$arr['link_apk'] = '';
		}

			
		if ($opt_themes['bahasa_on']) {
			if (!empty($arr['mods'])) {
				$arr['mods']			= $tr->setSource()->setTarget($bahasa)->translate($arr['mods']);
				$arr['mods']			= str_replace('< ', '<', $arr['mods']);
				$arr['mods']			= str_replace('< /', '</', $arr['mods']);
				$arr['mods']			= str_replace('</ ', '</', $arr['mods']);
				$arr['mods']			= str_replace(' >', '>', $arr['mods']);
			}

			if (!empty($arr['full_mod'])) {
				$arr['full_mod']		= $tr->setSource()->setTarget($bahasa)->translate($arr['full_mod']);
				$arr['full_mod']		= str_replace('< ', '<', $arr['full_mod']);
				$arr['full_mod']		= str_replace('< /', '</', $arr['full_mod']);
				$arr['full_mod']		= str_replace('</ ', '</', $arr['full_mod']);
				$arr['full_mod']		= str_replace(' >', '>', $arr['full_mod']);
			}

			if (!empty($arr['article_content'])) {
				$arr['article_content']	= $tr->setSource()->setTarget($bahasa)->translate($arr['article_content']);
				$arr['article_content']	= str_replace('< ', '<', $arr['article_content']);
				$arr['article_content']	= str_replace('< /', '</', $arr['article_content']);
				$arr['article_content']	= str_replace('</ ', '</', $arr['article_content']);
				$arr['article_content']	= str_replace(' >', '>', $arr['article_content']);
			}
			$arr['summary_sc']		= $tr->setSource()->setTarget($bahasa)->translate($arr['summary_sc']);
		}

		if (empty($arr['app_name'])) {
			$arr['error']			= NO_ID;
			echo $arr['error'];
		}
 

		return $arr;
	}

/**
 * Thoroughly clean the full MOD features/description section
 * Removes junk attributes, scripts, empty tags, links (converts to bold),
 * and normalizes formatting – while preserving lists and paragraphs.
 *
 * @param string $text Raw MOD HTML
 * @return string Clean, safe HTML ready for post content
 */
private function clean_full_mod( $text )
{
    if ( empty( $text ) ) {
        return '';
    }

    // 1. Decode entities (&nbsp;, &#8211;, etc.)
    $text = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5 );
    $text = str_replace( '&nbsp;', ' ', $text );

    // 2. Remove scripts and comments
    $text = preg_replace( '/<script[^>]*>.*?<\/script>/is', '', $text );
    $text = preg_replace( '/<!--.*?-->/s', '', $text );

    // 3. Remove ALL attributes (including data-*, dir, etc.)
    $text = preg_replace( '/\s+(href|target|class|id|style|data-toggle|data-parent|dir|aria-[a-z]+|onclick|rel)=[\'"][^\'"]*[\'"]/', '', $text );

    // 4. Remove completely empty tags (multiple passes for nested)
    $text = preg_replace( '/<([^\/>]+)[^>]*>\s*<\/\1>/is', '', $text );
    $text = preg_replace( '/<([^\/>]+)[^>]*>\s*<\/\1>/is', '', $text );

    // 5. Remove unwanted block/inline tags but keep useful ones
    $text = preg_replace( '/<\/?(div|center|span)[^>]*>/i', '', $text );

    // 6. Convert <a>text</a> → <b>text</b> (as in your original intent)
    $text = preg_replace( '/<a[^>]*>(.*?)<\/a>/is', '<b>$1</b>', $text );

    // 7. Standardize bold tags
    $text = str_replace( ['<strong>', '</strong>'], ['<b>', '</b>'], $text );

    // 8. Allow only safe formatting tags (preserves lists, paragraphs, etc.)
    $allowed_tags = '<p><br><ul><ol><li><b><em><i><blockquote><h3><h4>';
    $text = strip_tags( $text, $allowed_tags );

    // 9. Normalize whitespace
    $text = preg_replace( '/\s+/', ' ', $text );

    // 10. Optional: Add line breaks after paragraphs/list items for better display
    $text = preg_replace( '/<\/(p|li)>/i', "</$1>\n", $text );

    return trim( $text );
}

/**
 * Clean scraped article content:
 * - Removes TOC, images/figures, scripts, comments
 * - Strips all attributes and links
 * - Removes empty tags and unwanted containers
 * - Preserves paragraphs, lists, bold/emphasis
 * - Normalizes whitespace and formatting
 *
 * @param string $text Raw article HTML
 * @return string Clean, safe HTML for WordPress post content
 */
private function clean_article_sc( $text )
{
    if ( empty( $text ) ) {
        return '';
    }

    // 1. Decode entities first
    $text = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5 );

    // 2. Remove specific unwanted sections
    $text = preg_replace( '/<div id="toc_container"[^>]*>.*?<\/div>/is', '', $text );        // Table of Contents
    $text = preg_replace( '/<div class="wp-block-image"[^>]*>.*?<\/div>/is', '', $text );   // WP image blocks
    $text = preg_replace( '/<figure[^>]*>.*?<\/figure>/is', '', $text );                   // Figures (common wrappers)

    // 3. Remove images, scripts, comments
    $text = preg_replace( '/<img[^>]*>/is', '', $text );
    $text = preg_replace( '/<script[^>]*>.*?<\/script>/is', '', $text );
    $text = preg_replace( '/<!--.*?-->/s', '', $text );

    // 4. Remove ALL attributes (href, class, id, style, target, data-*, etc.)
    $text = preg_replace( '/\s+(href|target|class|id|style|data-[a-z-]+|aria-[a-z]+|onclick|rel)=[\'"][^\'"]*[\'"]/', '', $text );

    // 5. Remove completely empty tags (multiple passes for nested empties)
    $text = preg_replace( '/<([^\/>]+)[^>]*>\s*<\/\1>/is', '', $text );
    $text = preg_replace( '/<([^\/>]+)[^>]*>\s*<\/\1>/is', '', $text );

    // 6. Remove unwanted container tags
    $text = preg_replace( '/<\/?(div|center|span|section)[^>]*>/i', ' ', $text );

    // 7. Standardize bold tags
    $text = str_replace( ['<strong>', '</strong>'], ['<b>', '</b>'], $text );

    // 8. Allow only safe, useful formatting tags
    $allowed_tags = '<p><br><ul><ol><li><b><em><i><blockquote><h2><h3><h4><h5><h6>';
    $text = strip_tags( $text, $allowed_tags );

    // 9. Normalize whitespace and improve readability
    $text = preg_replace( '/\s+/', ' ', $text );
    $text = preg_replace( '/<\/(p|li|h[2-6]|blockquote)>/i', "</$1>\n", $text );

    return trim( $text );
}

}
