<?php

if ( ! defined( 'ABSPATH' ) ) exit; 
 
class StructurCode 
{
    private $Go_Curl;
    private $is_ajax;
	private $options = []; // Lebih baik inisialisasi di property

    public function __construct() 
	{
        $this->Go_Curl = new Go_Curl();
        $this->is_ajax = defined('DOING_AJAX') && DOING_AJAX;
		
		// Ambil semua pengaturan theme (status post, limit screenshot, shortener, dll)
		// Pengaturan ini akan menentukan perilaku import (misal: publish langsung atau draft)
		$this->options = $this->get_theme_option();
    }

	private function get_theme_option()
	{
		// Akses variabel global yang menyimpan semua opsi theme
		global $opt_themes;

		// Casting ke array untuk memastikan format selalu array (aman jika null atau bukan array)
		return (array) $opt_themes;
	}
	
	
	// Helper output error (sesuai mode AJAX atau bukan)
    private function output_error($message)
    {
        if ($this->is_ajax) {
            wp_send_json_error(['message' => $message]);
        } else {
            echo '<div class="notice notice-error"><p>' . esc_html($message) . '</p></div>';
        }
    }

	// Helper output error (sesuai mode AJAX atau bukan)
    private function output_error_url($message)
    {
        if ($this->is_ajax) {
            wp_send_json_error(['message' => $message]);
        } else {
            echo '<div class="notice notice-error"><p>' . wp_kses_post($message) . '</p></div>';
        }
    }

    private function show_notice($type, $message) 
	{
        $class = ($type === 'error') ? 'notice-error' : 'notice-warning';
        echo '<div class="notice ' . $class . '"><p>' . $message . '</p></div>';
    } 	
	 
	 
    private function error($message) 
	{
        if ($this->is_ajax) {
            echo '<div class="alert alert-danger">'.$message.'</div>';
            exit;
        }

        return [
            'error'   => true,
            'message' => $message
        ];
    }
	
    // ========================================================
    // Fungsi-fungsi helper regex (untuk parsing/scraping)
    // ========================================================
	/**
     * Debug menggunakan file_get_contents
     *
     * @param string $url
     * @return array
     */
    public function debug_file_get_contents($url)
    {
        $start = microtime(true);

        $context = stream_context_create([
            'http' => [
                'method'  => 'GET',
                'timeout' => 30,
                'header'  => implode("\r\n", [
                    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
                    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                    'Accept-Language: en-US,en;q=0.9',
                    'Referer: https://www.google.com/',
                ])
            ],
            'ssl' => [
                'verify_peer'      => false,
                'verify_peer_name' => false,
            ]
        ]);

        $html = @file_get_contents($url, false, $context);
        $time = round(microtime(true) - $start, 3);
        $error = error_get_last();

        // Deteksi body kosong (Cloudflare / JS protection)
        if ($html !== false && strlen(trim($html)) === 0) {
            return [
                'urk'			=> $url,
                'method'       	=> 'file_get_contents',
                'success'      	=> false,
                'time'         	=> $time . ' sec',
                'error'        	=> 'EMPTY BODY (Cloudflare / JS protection)',
                'response_hdr' 	=> $http_response_header ?? [],
            ];
        }

        return [
			'urk'       	=> $url,
            'method'       	=> 'file_get_contents',
            'success'      	=> $html !== false,
            'time'         	=> $time . ' sec',
            'error'        	=> $html === false ? ($error['message'] ?? 'unknown error') : null,
            'response_hdr' 	=> $http_response_header ?? [],
        ];
    }

	public function fetchWithCloudflareBypass(string $url): array
	{
		// ===============================
		// Inisialisasi hasil default
		// ===============================
		$result = [
			'url'            => $url,
			'success'        => false,   // Apakah scraping berhasil
			'method'         => null,    // Metode yang digunakan (wp_remote_get, file_get_contents, dll.)
			'time'           => null,    // Waktu eksekusi
			'html_length'    => 0,       // Panjang HTML hasil scraping
			'status_code'    => null,    // Status code HTTP (200, 404, 503, ...)
			'status_code2'    => $this->http_respon($url), // ← Ambil HTTP status code via cURL
			'title'          => null,    // Title halaman
			'h1'             => null,    // H1 halaman
			'mod_features'   => null,    // Fitur MOD dari judul
			'size'           => null,    // Ukuran file APK
			'description'    => null,    // Deskripsi singkat
			'download_link'  => null,    // Link download
			'error'          => null,    // Pesan error jika gagal
			'response_hdr'   => [],      // Header response dari server
		];

		// ===============================
		// User Agent & Header standar
		// ===============================
		$user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';

		$headers = [
			'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
			'Accept-Language' => 'en-US,en;q=0.9',
			'Accept-Encoding' => 'gzip, deflate',
			'Connection'      => 'keep-alive',
		];

		$html = null; // Variabel untuk menyimpan HTML hasil scraping

		// ===============================
		// STEP 1 — wp_remote_get
		// ===============================
		$start = microtime(true); // Catat waktu mulai

		$response = wp_remote_get($url, [
			'timeout'     => 30,
			'user-agent'  => $user_agent,
			'headers'     => $headers,
			'sslverify'   => true,
			'redirection' => 5,
		]);

		$result['time'] = round(microtime(true) - $start, 3) . ' sec';

		if (!is_wp_error($response)) {
			// Ambil semua header dan status code
			$result['response_hdr'] = wp_remote_retrieve_headers($response)->getAll();
			$result['status_code'] = wp_remote_retrieve_response_code($response);
		}

		// Cek jika response HTTP 200 dan bukan Cloudflare challenge
		if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
			$body = wp_remote_retrieve_body($response);
			if ($body && $this->isNotCloudflareChallenge($body)) {
				$html = $body;
				$result['method'] = 'wp_remote_get'; // Tandai metode yang berhasil
			}
		}

		// ===============================
		// STEP 2 — file_get_contents
		// ===============================
		if (!$html) { // Jika STEP 1 gagal
			$start = microtime(true);

			$context = stream_context_create([
				'http' => [
					'method'  => 'GET',
					'timeout' => 30,
					'header'  => implode("\r\n", [
						'User-Agent: ' . $user_agent,
						'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
						'Accept-Language: en-US,en;q=0.9',
						'Referer: https://www.google.com/',
					]),
				],
				'ssl' => [
					'verify_peer'      => false,
					'verify_peer_name' => false,
				],
			]);

			$html_try = @file_get_contents($url, false, $context); // Ambil HTML
			$time     = round(microtime(true) - $start, 3);
			$error    = error_get_last();

			$result['time'] = $time . ' sec';
			$result['response_hdr'] = $http_response_header ?? [];

			// Cek jika body kosong
			if ($html_try !== false && strlen(trim($html_try)) === 0) {
				$result['method'] = 'file_get_contents';
				$result['error']  = 'EMPTY BODY (Cloudflare / JS protection)';
			}

			// Cek jika body valid dan bukan Cloudflare challenge
			if ($html_try !== false && strlen(trim($html_try)) > 0 && $this->isNotCloudflareChallenge($html_try)) {
				$html = $html_try;
				$result['method'] = 'file_get_contents';
			}
		}

		// ===============================
		// STEP 3 — scrape_site (jika ada)
		// ===============================
		if (!$html && function_exists('scrape_site')) {
			$start = microtime(true);
			$tmp   = scrape_site($url);
			$result['time'] = round(microtime(true) - $start, 3) . ' sec';
			$result['response_hdr'] = [];

			if ($tmp && $this->isNotCloudflareChallenge($tmp)) {
				$html = $tmp;
				$result['method'] = 'scrape_site';
			}
		}

		// ===============================
		// STEP 4 — fast_get_content (jika ada)
		// ===============================
		if (!$html && method_exists($this, 'fast_get_content')) {
			$start = microtime(true);
			$tmp   = $this->fast_get_content($url);
			$result['time'] = round(microtime(true) - $start, 3) . ' sec';
			$result['response_hdr'] = [];

			if ($tmp && $this->isNotCloudflareChallenge($tmp)) {
				$html = $tmp;
				$result['method'] = 'fast_get_content';
			}
		}

		// ===============================
		// STEP 5 — FlareSolverr (jika semua gagal)
		// ===============================
		if (!$html) {
			$start = microtime(true);

			$solver_response = wp_remote_post('http://127.0.0.1:8191/v1', [
				'headers' => ['Content-Type' => 'application/json'],
				'timeout' => 120,
				'body'    => wp_json_encode([
					'cmd'        => 'request.get',
					'url'        => $url,
					'maxTimeout' => 90000,
					'headers'    => ['User-Agent' => $user_agent],
				]),
			]);

			$result['time'] = round(microtime(true) - $start, 3) . ' sec';

			if (!is_wp_error($solver_response)) {
				$result['response_hdr'] = wp_remote_retrieve_headers($solver_response)->getAll();
				$data = json_decode(wp_remote_retrieve_body($solver_response), true);
				if (
					isset($data['status']) &&
					$data['status'] === 'ok' &&
					!empty($data['solution']['response']) &&
					$this->isNotCloudflareChallenge($data['solution']['response'])
				) {
					$html = $data['solution']['response'];
					$result['method'] = 'flaresolverr';
				}
			}
		}

		// ===============================
		// Total fail jika semua metode gagal
		// ===============================
		if (!$html) {
			$result['error'] = $result['error'] ?: 'All bypass methods failed (Cloudflare active)';
			return $result;
		}

		// ===============================
		// Ekstraksi data dari HTML
		// ===============================
		$result['success']     = true;
		$result['html_length'] = strlen($html);

		// TITLE & H1
		$title = $this->match('/<title>(.*?)<\/title>/is', $html, 1);
		$h1    = $this->match('/<h1[^>]*>(.*?)<\/h1>/is', $html, 1);

		$result['title'] = $title ? html_entity_decode(trim($title), ENT_QUOTES, 'UTF-8') : null;
		$result['h1']    = $h1 ? trim(strip_tags($h1)) : null;

		// DESCRIPTION (og:description, truncate 80 chars)
		$description =
			$this->match('/<meta[^>]+property=["\']og:description["\'][^>]+content=["\'](.*?)["\']/is', $html, 1)
			?: $this->match('/<meta[^>]+content=["\'](.*?)["\'][^>]+property=["\']og:description["\']/is', $html, 1);

		if ($description) {
			$description = html_entity_decode(trim($description), ENT_QUOTES, 'UTF-8');
			if (mb_strlen($description, 'UTF-8') > 80) {
				$description = mb_substr($description, 0, 80, 'UTF-8');
				$description = rtrim($description, " \t\n\r\0\x0B.,!?:;-") . '…';
			}
			$result['description'] = $description;
		}

		// MOD FEATURES → ambil isi kurung terakhir dari title
		if ($title && preg_match_all('/\(([^)]+)\)/', $title, $m)) {
			$result['mod_features'] = trim(end($m[1]));
		}

		// SIZE
		if (preg_match('/Download\s*\(([\d\.]+\s*(?:MB|GB))\)/i', $html, $m)) {
			$result['size'] = $m[1];
		}

		// DOWNLOAD LINK
		$dl = $this->match('/href=["\']([^"\']+)["\'][^>]*>\s*(?:Download|Direct Download)/i', $html, 1);
		$result['download_link'] = $dl ?: null;

		return $result;
	}

    /**
     * Deteksi apakah halaman masih menampilkan Cloudflare challenge
     *
     * @param string $html Konten HTML halaman
     * @return bool true = aman (bukan challenge), false = masih challenge
     */
    private function isNotCloudflareChallenge(string $html): bool
    {
        $indicators = [
            'Checking your browser',
            'cf-browser-verification',
            'Attention Required!',
            'cloudflare.com',
            'DDoS protection',
            'ray-id',
            'cf-chl-bypass',
            'turnstile',
            'cf-turnstile-response',
            'just a moment',           // tambahan variasi baru
            'please wait while your request is being verified',
        ];

        foreach ($indicators as $indicator) {
            if (stripos($html, $indicator) !== false) {
                return false; // ini challenge page
            }
        }

        return true; // aman, bukan halaman Cloudflare
    }
	
    /**
     * Mencari semua pasangan key-value menggunakan regex
     * Cocok untuk parsing atribut HTML, JSON-like string, dll
     *
     * @param string $regex Pola regex dengan group untuk key dan value
     * @param string $str String yang akan diparsing
     * @param int $keyIndex Index group untuk key (default: 1)
     * @param int $valueIndex Index group untuk value (default: 2)
     * @return array Array dengan format [key => value]
     */
    public function match_all_key_value($regex, $str, $keyIndex = 1, $valueIndex = 2) 
	{
        $arr = [];
        if (preg_match_all($regex, $str, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $m) {
                $key = trim($m[$keyIndex] ?? '');
                $value = trim($m[$valueIndex] ?? '');
                if ($key !== '') {
                    $arr[$key] = $value;
                }
            }
        }
        return $arr;
    }

    /**
     * Mencari semua kecocokan regex dan mengembalikan array hasil pada index tertentu
     *
     * @param string $regex Pola regex
     * @param string $str String input
     * @param int $index Index group yang diinginkan (default: 0 = full match)
     * @return array|false Array hasil atau false jika tidak ada kecocokan
     */
    public function match_all($regex, $str, $index = 0) 
	{
        if (preg_match_all($regex, $str, $matches) === false) {
            return false;
        }
        return $matches[$index] ?? [];
    }

    /**
     * Mencari satu kecocokan pertama saja
     *
     * @param string $regex Pola regex
     * @param string $str String input
     * @param int $index Index group yang diinginkan (default: 0 = full match)
     * @return string|false Hasil match atau false jika tidak ditemukan
     */
    public function match($regex, $str, $index = 0) 
	{
        if (preg_match($regex, $str, $match)) {
            return $match[$index] ?? '';
        }
        return false;
    }
	
	public function http_respon($url) 
	{
        if (empty($url) || !filter_var($url, FILTER_VALIDATE_URL)) {
            return false;
        }

        $ch = curl_init();

        curl_setopt_array($ch, [
            CURLOPT_URL            => $url,
            CURLOPT_HEADER         => true,
            CURLOPT_NOBODY         => true,        // Hanya ambil header (tidak download body)
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_TIMEOUT        => 15,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_SSL_VERIFYPEER => false,       // Opsional: nonaktifkan verifikasi SSL jika sering error
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_USERAGENT      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
        ]);

        $head = curl_exec($ch);

        // Ambil HTTP status code
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        // Cek error cURL
        if ($head === false) {
            $curl_error = curl_error($ch);
            curl_close($ch);
            // Optional: log error untuk debug
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log("http_respons() failed for URL: $url | Error: $curl_error");
            }
            return false;
        }

        curl_close($ch);

        // Optional: delay acak (untuk menghindari rate limit, tapi hanya jika diperlukan)
        // sleep(rand(1, 5)); // Uncomment jika memang ingin delay

        return $httpCode;
    }
	
	public function fast_get_content($url) 
	{
		$ch = curl_init($url);
		curl_setopt_array($ch, [
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_TIMEOUT        => 10,               // jangan terlalu lama
			CURLOPT_CONNECTTIMEOUT => 5,
			CURLOPT_FOLLOWLOCATION => true,
			CURLOPT_MAXREDIRS      => 5,
			CURLOPT_SSL_VERIFYPEER => false,            // matikan jika target SSL bermasalah (hati-hati!)
			CURLOPT_USERAGENT      => 'Mozilla/5.0 (compatible; FastBot/1.0)',
			CURLOPT_ACCEPT_ENCODING => '',              // aktifkan gzip/deflate/brotli otomatis
			CURLOPT_HEADER         => false,
			CURLOPT_NOBODY         => false, 
		]); 
		$response = curl_exec($ch);
		curl_close($ch);
		return $response ?: ''; // fallback kosong jika gagal
	}

    /**
     * Mengambil salah satu API key Scrape.do secara random dari pengaturan tema
     * 
     * @return string|false Token API yang dipilih atau false jika tidak ada token yang valid
     */
	public function scrape_do_tokens() 
	{   
		// Ambil data dari pengaturan tema 
		$api_keys = $this->options['api_key_scrape'] ?? [];

		// Pastikan $api_keys selalu array
		if (!is_array($api_keys)) {
			$api_keys = [];
		}

		// Bersihkan token kosong & whitespace
		$api_keys = array_filter(
			array_map('trim', $api_keys),
			function($key) {
				return !empty($key) && is_string($key) && strlen($key) > 10;
			}
		);

		// Jika kosong, kembalikan false
		if (empty($api_keys)) {
			error_log('No valid API key in theme settings.');
			return false;
		}

		// Pilih token acak
		return $api_keys[array_rand($api_keys)];
	}
 
    public function scrape_do_tokens1() 
	{ 	
        // Ambil data dari pengaturan tema 
		$api_keys = $this->options['api_key_scrape'] ?? [];
		
        // Pastikan array dan bersihkan nilai kosong + whitespace
        $api_keys = array_filter(
            array_map('trim', $api_keys),
            function($key) {
                return !empty($key) && is_string($key) && strlen($key) > 10;
            }
        );

        // Jika setelah dibersihkan masih kosong
        if (empty($api_keys)) {
            // Optional: tampilkan notifikasi di admin area
            if (is_admin() && current_user_can('manage_options')) {
                add_action('admin_notices', function() {
                    echo '<div class="notice notice-error is-dismissible">';
                    echo '<p><strong>Error:</strong> no valid API key in theme settings.</p>';
                    echo '</div>';
                });
            }

            // Bisa juga log ke error_log untuk debugging
            error_log('no valid API key in api key');

            return false;
        }


        // Pilih secara acak
        $selected_token = $api_keys[array_rand($api_keys)];

        // Optional: logging (untuk monitoring pemakaian token)
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log("API token used: " . substr($selected_token, 0, 12) . "...");
        }

        return $selected_token;
    }


    // ===============================
    // MASK API TOKEN
    // ===============================
    public function mask_api_token($token) { 
        if (strlen($token) < 10) return str_repeat('*', strlen($token));

        return substr($token, 0, 5)
            . ' ' . str_repeat('* ', 8)
            . substr($token, -4);
    }


    /**
     * Fungsi scrapedox: Mengambil konten URL menggunakan proxy Scrape.do
     * Token diambil secara random melalui scrape_do_tokens()
     *
     * @param string $url URL yang akan di-scrape
     * @return string|false Isi HTML atau false jika gagal
     */
    public function scrapedo($url) 
	{
        $curl = curl_init();

        // Set opsi dasar
        curl_setopt_array($curl, [
            CURLOPT_URL            => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER         => false,
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_SSL_VERIFYPEER => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_TIMEOUT        => 45,
            CURLOPT_CONNECTTIMEOUT => 15,
            CURLOPT_USERAGENT      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
            CURLOPT_HTTPHEADER     => [
                'Accept: */*',
                'Accept-Language: en-US,en;q=0.9',
            ],
        ]);

        // Ambil token proxy secara random
        $apikey = $this->scrape_do_tokens();

		
		if (empty($apikey)) {
			$this->output_error_url("No valid token from Api Key. Please Add Your Api Key or Token On <a href='/wp-admin/admin.php?page=_options&tab=20'>Panel Theme</a> Setting.");
			curl_close($curl);
			return false;
		}		
		 

        // Format proxy Scrape.do
        $proxy = "http://{$apikey}:@proxy.scrape.do:8080";

        curl_setopt($curl, CURLOPT_PROXY, $proxy);

        // Eksekusi request
        $response = curl_exec($curl);

        // Cek error cURL
        if ($response === false) {
            $curl_error = curl_error($curl);
            $this->output_error("cURL error via proxy: " . $curl_error.", Please Click Reset Importer On Admin Bar" );
            curl_close($curl);
            return false;
        }

        // Cek HTTP status code
        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        if ($http_code >= 400) {
            $this->output_error_url("proxy returns status $http_code for URL: $url, Please <a href='/wp-admin/admin.php?page=sc-auto-post&ai_force_reset=1'>Click Reset</a> Importer On 🚨 Admin Bar.");
            curl_close($curl);
            return false;
        }

        curl_close($curl);

        // Optional: log untuk debug
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log("success for URL: $url (token: " . substr($apikey, 0, 12) . "...)");
        }

        return $response;
    }

    // Jika method api_randx() belum ada, tambahkan contoh sederhana ini
    public function api_rand() 
	{  		
        $api_keys = !empty($this->options['api_key_scrape']) ? (array) $this->options['api_key_scrape'] : []; 

        // Bersihkan dan filter token kosong
        $api_keys = array_filter(array_map('trim', $api_keys));

        if (empty($api_keys)) {
            return false;
        }

        return $api_keys[array_rand($api_keys)];
    }	
		
	/**
	 * Fallback: Ambil konten langsung pakai cURL + proxy jika method fast_get_content gagal
	 */
	private function get_via_curl_proxy($url, $options)
	{
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_TIMEOUT, $options['timeout']);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $options['connect_timeout']);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $options['follow_redirect']);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array_map(function($k, $v) { return "$k: $v"; }, array_keys($options['headers']), $options['headers']));
		curl_setopt($ch, CURLOPT_PROXY, $options['proxy']);
		curl_setopt($ch, CURLOPT_PROXYTYPE, $options['proxytype']);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $options['ssl_verifypeer']);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $options['ssl_verifyhost']);

		$html = curl_exec($ch);
		if (curl_errno($ch)) {
			// Log error jika perlu: error_log(curl_error($ch));
		}
		curl_close($ch);

		return $html ?: '';
	}

	/**
	 * Render tombol Clear Cache untuk semua transient terkait scraper & detail item
	 * Aman dengan nonce, konfirmasi JS, dan notifikasi sukses
	 *
	 * @return string HTML tombol + handler PHP
	 */
	public function renderClearCacheButton(): string
	{
		ob_start();

		// Handler penghapusan cache (jika tombol diklik)
		if (isset($_GET['clear_all_scraper_cache']) && check_admin_referer('clear_scraper_cache_nonce')) {
			global $wpdb;

			// Hapus cache listing (5play, apkmody, dll)
			$wpdb->query(
				"DELETE FROM $wpdb->options 
				 WHERE option_name LIKE '_transient_5play_listing_%' 
				 OR option_name LIKE '_transient_apkmody_listing_%' 
				 OR option_name LIKE '_transient_getmodsapk_listing_%' 
				 OR option_name LIKE '_transient_liteapks_listing_%'"
			);

			// Hapus cache detail item (MOD + title dari render_app_item)
			$wpdb->query(
				"DELETE FROM $wpdb->options 
				 WHERE option_name LIKE '_transient_detail_mod_item_%'"
			);

			// Tampilkan notifikasi sukses
			echo '<div class="notice notice-success is-dismissible"><p><strong>Cache cleared successfully!</strong> All scraper data and item details will be refreshed the next time it is loaded.</p></div>';
		}

		// Buat URL tombol dengan nonce
		$clear_url = wp_nonce_url(
			add_query_arg('clear_all_scraper_cache', '1', admin_url('admin.php?page=sc-auto-post')), // ganti page slug jika berbeda
			'clear_scraper_cache_nonce'
		);

		?>
		<a href="<?= esc_url($clear_url) ?>"
		   class="button button-secondary button-hero"
		   style="margin: 10px 0; background: #dc3232; color: white; border-color: #b32d2e;"
		   onclick="return confirm('Yakin ingin menghapus SEMUA cache scraper dan detail item?\nIni akan memaksa pengambilan data baru dari situs sumber saat halaman berikutnya di-load.');">
			<span class="dashicons dashicons-trash" style="vertical-align: middle; margin-right: 5px;"></span>
			Clear All Scraper & Detail Cache
		</a>
		<?php

		return ob_get_clean();
	}
	
	/**
	 * Mencari package name (App ID) Google Play berdasarkan judul aplikasi
	 * Menggunakan scraping langsung ke halaman pencarian Play Store
	 *
	 * Catatan: Di tahun 2026 metode ini sering gagal karena perlindungan bot yang ketat.
	 *          Keberhasilan ~20–50% tergantung IP, waktu, dan judul aplikasi.
	 *          Lebih baik gunakan API atau data dari halaman detail jika memungkinkan.
	 *
	 * @param string $title Judul aplikasi yang akan dicari
	 * @return string|null Package name (contoh: com.whatsapp) atau null jika gagal
	 */
	 
	public function getAppIDs($title)
	{
		if (empty(trim($title))) {
			return null;
		}

		$query = urlencode(trim($title));
		$search_url = "https://play.google.com/store/search?q={$query}&c=apps&hl=en_US&gl=US";

		$ch = curl_init($search_url);

		// Set konfigurasi yang lebih aman & realistis
		curl_setopt_array($ch, [
			CURLOPT_RETURNTRANSFER     => true,
			CURLOPT_FOLLOWLOCATION     => true,
			CURLOPT_TIMEOUT            => 15,
			CURLOPT_CONNECTTIMEOUT     => 10,
			CURLOPT_SSL_VERIFYPEER     => true,          // Aktifkan kembali di produksi!
			CURLOPT_SSL_VERIFYHOST     => 2,
			CURLOPT_USERAGENT          => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
			CURLOPT_HTTPHEADER         => [
				'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
				'Accept-Language: en-US,en;q=0.9',
				'Accept-Encoding: gzip, deflate',
				'Connection: keep-alive'
			],
			CURLOPT_ENCODING           => 'gzip, deflate', // support kompresi
		]);

		$html = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);

		if ($httpCode !== 200 || empty($html) || strpos($html, 'captcha') !== false) {
			return null;
		}

		// Pola regex yang lebih robust untuk struktur 2025–2026
		$patterns = [
			// Pola paling umum saat ini (data attributes atau href langsung)
			'/data-item-id="([a-z][a-z0-9_]*(\.[a-z0-9_]+)+)"/i',
			'/href="\/store\/apps\/details\?id=([a-z0-9\._]+)"/i',
			'/\/details\?id=([a-z0-9\._]+)/i',
			'/play\.google\.com\/store\/apps\/details\?id=([a-z0-9\._]+)/i'
		];

		foreach ($patterns as $pattern) {
			if (preg_match($pattern, $html, $match)) {
				$package = trim($match[1]);
				if ($this->is_valid_playstore_id($package)) {
					return $package;
				}
			}
		}

		return null;
	}	
	
	
	public function getAllAppIDSearch($title)
	{
		if (empty(trim($title))) {
			return [];
		}

		$query = urlencode(trim($title));
		$search_url = "https://play.google.com/store/search?q={$query}&c=apps&hl=en_US&gl=US";

		$ch = curl_init($search_url);

		curl_setopt_array($ch, [
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_FOLLOWLOCATION => true,
			CURLOPT_TIMEOUT        => 15,
			CURLOPT_CONNECTTIMEOUT => 10,
			CURLOPT_SSL_VERIFYPEER => true,
			CURLOPT_SSL_VERIFYHOST => 2,
			CURLOPT_USERAGENT      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
			CURLOPT_ENCODING       => 'gzip, deflate',
		]);

		$html = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);

		if ($httpCode !== 200 || empty($html) || stripos($html, 'captcha') !== false) {
			return [];
		}

		preg_match_all(
			'/\/store\/apps\/details\?id=([a-zA-Z0-9\._]+)/',
			$html,
			$matches
		);

		$results = [];
		$limit   = 10;
		$count   = 0;

		if (!empty($matches[1])) {
			foreach ($matches[1] as $package) {

				if ($count >= $limit) {
					break;
				}

				$package = trim($package);

				if (!$this->is_valid_playstore_id($package)) {
					continue;
				}

				// Hindari duplikat
				if (isset($results[$package])) {
					continue;
				}

				$results[$package] = [
					'appid'   => $package,
					'appname' => $this->GetAppsTitle($package), 
					'version' => 'v'.$this->getAppsVersi($package) ?: '',
					'poster'  => $this->GetAppsPoster($package),
					'summary' => $this->GetAppsSummary($package),
					'category' => $this->getAppsCategory($package) ?: '',
					'developer' => $this->getAppsDeveloperName($package) ?: '', 
					'update' => $this->getAppsUpdate($package) ?: '', 
					'link'    => $this->getAppsLink($package),
				];

				$count++;
			}
		}

		return array_values($results);
	}


	/* public function getAllAppIDSearch22222{		
		string $title,
		string $lang = 'en_US',
		string $country = 'US'
	): string {
	
		if (empty(trim($title))) {
			return [];
		}

		//$gplay = new GPlayApps($defaultLocale = 'en_US', $defaultCountry = 'US');
		
		$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);

		try {
			$results = $gplay->search(trim($title), $maxResults = 15); // limit 15

			$appids = [];
			foreach ($results as $app) {
			 
				$package = $app->getPackageId(); // atau $app->getId()
				if ($package && $this->is_valid_playstore_id($package)) {
					$appids[$package] = [
						'appid' => $package,
						'link' => 'https://play.google.com/store/apps/details?id=' . $package,
					];
				}
			}

			return array_values($appids);
		} catch (GooglePlayException $e) {
			error_log("GPlay search error: " . $e->getMessage());
			return [];
		}
	} */

	
	public function getAppsLink_Asli(
		string $packageId,
		string $lang = 'en_US',
		string $country = 'US'
	): string {   // ← changed return type to string
		$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);
		
		try {
			$appInfo = $gplay->getAppInfo($packageId);
			return $appInfo->getUrl();
		} catch (\Nelexa\GPlay\Exception\GooglePlayException $e) {
			return "Not found or error: " . $e->getMessage();
		}
	}
	
	public function getAppsCategory(
		string $packageId,
		string $lang = 'en_US',
		string $country = 'US'
	): string {   // ← changed return type to string
		$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);
		
		try {
			$appInfo = $gplay->getAppInfo($packageId);
			return $appInfo->getCategory()->getName();
		} catch (\Nelexa\GPlay\Exception\GooglePlayException $e) {
			return "Not found or error: " . $e->getMessage();
		}
	}
		
	public function getAppsDeveloperName(
		string $packageId,
		string $lang = 'en_US',
		string $country = 'US'
	): string {   // ← changed return type to string
		$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);
		
		try {
			$appInfo = $gplay->getAppInfo($packageId);
			return $appInfo->getDeveloperName();
		} catch (\Nelexa\GPlay\Exception\GooglePlayException $e) {
			return "Not found or error: " . $e->getMessage();
		}
	}
	
	public function getAppsUpdate(
		string $packageId,
		string $lang = 'en_US',
		string $country = 'US'
	): string {   // ← changed return type to string
		$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);
		
		try {
			$appInfo = $gplay->getAppInfo($packageId);
			return $appInfo->getUpdated()->format('M d, Y');
		} catch (\Nelexa\GPlay\Exception\GooglePlayException $e) {
			return "Not found or error: " . $e->getMessage();
		}
	}
		
	public function getAppsVersi(
		string $packageId,
		string $lang = 'en_US',
		string $country = 'US'
	): string {

		$foundVersion = null;

		/* ============================
		 * STEP 1 — Nelexa API (Prioritas)
		 * ============================ */
		if (class_exists('\Nelexa\GPlay\GPlayApps')) {
			try {
				$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);
				$appInfo = $gplay->getAppInfo($packageId);
				$version = $appInfo->getAppVersion();
				if ($version) {
					return $version; // langsung return karena prioritas tertinggi
				}
			} catch (\Throwable $e) {
				// gagal ambil versi dari Nelexa API, lanjut ke fallback
			}
		}

		/* ============================
		 * STEP 2 — APK Sites HTML (Fallback)
		 * ============================ */
		$apkSites = [
			'apkcombo' => "https://apkcombo.com/genericApp/{$packageId}", 
			'apkgk'    => "https://apkgk.com/{$packageId}",
		];

		foreach ($apkSites as $url) {
			$html = $this->curlGet($url);
			if (!$html) continue;

			if (preg_match('/Version[:\s]*([0-9]+(?:\.[0-9]+){1,4})/i', $html, $m)) {
				return $m[1];
			}
		}

		return 'Not found';
	}

	// ===========================
	// Helper cURL GET
	// ===========================
	private function curlGet(string $url): string {
		$ch = curl_init($url);
		curl_setopt_array($ch, [
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_FOLLOWLOCATION => true,
			CURLOPT_TIMEOUT => 20,
			CURLOPT_CONNECTTIMEOUT => 10,
			CURLOPT_SSL_VERIFYPEER => true,
			CURLOPT_SSL_VERIFYHOST => 2,
			CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
			CURLOPT_HTTPHEADER => [
				'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
				'Accept-Language: en-US,en;q=0.9',
				'Cache-Control: no-cache',
				'Pragma: no-cache',
			],
		]);
		$html = curl_exec($ch);
		curl_close($ch);
		return $html ?: '';
	}

	public function debugGoogleSnippetMulti(string $packageId, string ...$sites): void {
		foreach ($sites as $site) {
			echo "===============================\n";
			echo "Site: $site\n";

			$query = urlencode("site:$site $packageId version");
			$googleSearchUrl = "https://www.google.com/search?q=$query";
			echo "Google Search URL: $googleSearchUrl\n\n";

			$html = $this->curlGet($googleSearchUrl);

			if (empty($html)) {
				echo "Gagal ambil halaman Google Search.\n";
				continue;
			}

			// ===============================
			// 1️⃣ Ambil versi dari <em>Versi x.y.z</em>
			// ===============================
			if (preg_match_all('/<em>\s*Versi\.?\s*([0-9]+(?:\.[0-9]+){1,3})\s*<\/em>/i', $html, $matches)) {
				echo "===== Found Versions =====\n";
				foreach ($matches[1] as $idx => $ver) {
					echo "[$idx] $ver\n";
				}
			} else {
				echo "Tidak ada versi ditemukan.\n";
			}

			// ===============================
			// 2️⃣ Ambil judul dari snippet <h3>
			// ===============================
			if (preg_match_all('/<h3[^>]*>(.*?)<\/h3>/is', $html, $titles)) {
				echo "===== Found Titles =====\n";
				foreach ($titles[1] as $idx => $title) {
					$cleanTitle = strip_tags(html_entity_decode($title));
					echo "[$idx] $cleanTitle\n";
				}
			} else {
				echo "Tidak ada judul ditemukan.\n";
			}

			// ===============================
			// 3️⃣ Preview raw snippet Google
			// ===============================
			echo "\n===== Raw snippet preview =====\n";
			if (preg_match_all('/<div class="kb0PBd A9Y9g".*?>(.*?)<\/div>/is', $html, $snippets)) {
				foreach ($snippets[1] as $idx => $snip) {
					$clean = strip_tags($snip);
					echo "[$idx] $clean\n-------------------\n";
				}
			}

			echo "\n";
		}
	}

	public function getAppsLink(string $packageId, string $lang = 'en_US', string $country = 'US'): string {
		try {
			$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);
			$appInfo = $gplay->getAppInfo($packageId);
			return $appInfo->getUrl() ?? '';
		} catch (\Exception $e) {
			return '';
		}
	}

	public function GetAppsPoster(string $packageId, string $lang = 'en_US', string $country = 'US'): string {
		try {
			$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);
			$appInfo = $gplay->getAppInfo($packageId);
			return $appInfo->getIcon()?->getUrl() ?? '';
		} catch (\Exception $e) {
			return '';
		}
	}

	public function GetAppsTitle(string $packageId, string $lang = 'en_US', string $country = 'US'): string {
		try {
			$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);
			$appInfo = $gplay->getAppInfo($packageId);
			return $appInfo->getName() ?? '';
		} catch (\Exception $e) {
			return '';
		}
	}
	
	public function GetAppsSummary(string $packageId, string $lang = 'en_US', string $country = 'US'): string {
		try {
			$gplay = new \Nelexa\GPlay\GPlayApps($lang, $country);
			$appInfo = $gplay->getAppInfo($packageId);
			return $appInfo->getSummary() ?? '';
		} catch (\Exception $e) {
			return '';
		}
	}
 
	public function get_all_imported_urls(): array
	{
		global $wpdb;

		$rows = $wpdb->get_col("
			SELECT DISTINCT meta_value
			FROM {$wpdb->postmeta}
			WHERE meta_key = '_sc_source_url'
		");

		return array_filter(array_map('esc_url_raw', $rows));
	}

	/**
	 * Membersihkan judul agar lebih mudah dicari di Play Store
	 */
	private function sanitize_app_title($title)
	{
		$title = html_entity_decode($title, ENT_QUOTES | ENT_HTML5);
		$title = preg_replace('/\s*(MOD|Premium|Unlocked|VIP|Hack|Cheat).*$/i', '', $title);
		$title = preg_replace('/\s*v?\.?\d+[\d\.\-\_\+]*.*$/i', '', $title); // hapus version
		$title = trim(preg_replace('/\s+/', ' ', $title));
		return $title;
	}
 
	/**
	 * Mencoba ekstrak App ID dari berbagai jenis URL
	 */
	private function extract_playstore_id_from_url($url)
	{
		if (empty($url)) {
			return null;
		}

		// Pola langsung
		if (preg_match('/id=([a-z0-9\._]+)/i', $url, $m)) {
			return $m[1];
		}

		// Pola di query string
		parse_str(parse_url($url, PHP_URL_QUERY), $query);
		if (!empty($query['id'])) {
			return trim($query['id']);
		}

		// Pola di path (kadang dipakai beberapa situs)
		if (preg_match('#/details/([a-z0-9\._]+)#i', $url, $m)) {
			return $m[1];
		}

		return null;
	}

	/**
	 * Ekstrak teks MOD dari judul halaman (khususnya 5play.org dan situs MOD APK serupa)
	 * Contoh input: "Download Motor Depot 1.3772 APK (MOD all cars are unlocked) for Android"
	 * Output: "All Cars Are Unlocked" atau "-" jika tidak ditemukan
	 *
	 * @param string $title Judul lengkap dari <title> tag
	 * @param string $source Sumber situs (default '5play' – bisa ditambah pola lain nanti)
	 * @return string MOD yang dibersihkan
	 */
	public function get_mod_by_title_source(string $title, string $source = '5play'): string
	{
		if (empty(trim($title))) {
			return '-';
		}

		$title = trim($title);

		// Pola utama 5play.org: hampir selalu ada di dalam kurung setelah versi
		$patterns = [
			// Pola paling umum: (MOD xxx yyy zzz)
			'/\((?:MOD\s+)?([^)]+?)\)/i',
			// Pola alternatif: [MOD ...] atau MOD: ...
			'/\[MOD\s+([^\]]+?)\]/i',
			'/MOD:\s*([^(\[]+?)(?:\s+APK|\s+for|\s*$)/i',
			// Pola longshot: ambil setelah versi sampai "for Android" atau akhir
			'/\d+(?:\.\d+)+.*?\(([^)]+)\).*?(?:for Android|$)/i',
		];

		foreach ($patterns as $pattern) {
			if (preg_match($pattern, $title, $matches)) {
				$mod_raw = trim($matches[1] ?? '');
				if (empty($mod_raw)) continue;

				// Bersihkan dan normalkan teks MOD
				$mod_raw = preg_replace('/\s+MOD\s*/i', ' ', $mod_raw);     // hapus kata MOD duplikat
				$mod_raw = preg_replace('/\s+and\s+/i', ', ', $mod_raw);     // ubah "and" jadi koma
				$mod_raw = preg_replace('/\s+-\s+|\s+•\s+/', ', ', $mod_raw); // ganti pemisah lain
				$mod_raw = ucwords(strtolower(trim($mod_raw)));              // kapital awal kata

				// Hapus kata umum yang tidak perlu jika ada
				$mod_raw = preg_replace('/^(All|Unlimited|Free|Premium)\s+/i', '$1 ', $mod_raw);

				if (strlen($mod_raw) > 3) {
					return $mod_raw;
				}
			}
		}

		// Fallback: cari keyword MOD umum di seluruh judul
		if (preg_match_all('/(unlocked|premium|mod|god|mega|free|no\s*ads|full|vip|all\s+[^ ]+)/i', $title, $matches)) {
			$found = array_unique(array_map('trim', $matches[0]));
			if (!empty($found)) {
				return ucwords(strtolower(implode(', ', $found)));
			}
		}

		// Jika masih tidak ketemu → tergantung source bisa ditambah logika khusus
		if ($source === '5play') {
			// 5play hampir selalu pakai (MOD ...), jika kosong mungkin bukan halaman MOD
			return 'No MOD info';
		}

		return '-';
	}

	/**
	 * Cek apakah URL gambar dapat diakses (versi ringan menggunakan wp_remote_head)
	 */
	public function url_exists($url)
	{
		// Jika bukan di WordPress, langsung anggap valid (hindari error fatal)
		if (!function_exists('wp_remote_head')) {
			return true;
		}

		$response = wp_remote_head($url, [
			'timeout'     => 4,
			'sslverify'   => false,
			'redirection' => 5,
			'httpversion' => '1.1',
		]);

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

		$code = wp_remote_retrieve_response_code($response);
		return ($code >= 200 && $code < 400);
	}

	/**
	 * Helper: Validasi format package name Android
	 */
	private function is_valid_playstore_id($id)
	{
		if (empty($id)) {
			return false;
		}
		return preg_match('/^[a-z][a-z0-9_]*(\.[a-z0-9][a-z0-9_]*)+$/i', $id);
	}

	public function renderImportNotification(): string
	{
		ob_start();
		?> 
 
<!-- ImportNotifModal Notifikasi dengan Progress Count + Judul Item -->
<div id="import-notification" class="import-notification" role="alert" style="display: none;">

	<!-- Tombol Close -->
	<button id="import-notification-close" style="position: absolute; top: 8px; right: 8px; background: transparent; border: none; font-size: 1.2em; cursor: pointer;display: none; ">&times;</button>
  
	<div class="notification-content">
	
	<div class="message">
		<h3><?php _e('Please wait', TEXT_DOMAIN); ?></h3>
		<p><?php _e('Do not close or refresh the page while the import is running...', TEXT_DOMAIN); ?></p>
	</div>

	</div>

	<div class="progress-section">
	<div class="progress-count">
	<span id="current-count">0</span> / <span id="total-count">0</span> <?php _e('items', TEXT_DOMAIN); ?>
	</div>
     
	<div class="current-item"><span id="current-item-title"></span></div>
    
	<!-- Edit link -->
	<div class="edit-link-section" id="edit-link-section" style="display: none; margin: 12px 0;">
	<a id="edit-post-link" href="#" target="_blank" class="edit-link"><?php _e('Edit Post →', TEXT_DOMAIN); ?></a>
	</div>

	<div class="loading-bar">
	<div class="loading-progress" id="progress-fill"></div>
	</div>
	
	</div>
</div>

<style>
#import-log-list{list-style:none;padding:0;margin:0;max-height:300px;overflow-y:auto;background:#f9fafb;border:1px solid #e5e7eb;border-radius:8px}
#import-log-list{-ms-overflow-style:none;scrollbar-width:none}
#import-log-list::-webkit-scrollbar{display:none}
.import-log-item{transition:background-color 0.15s ease}
.import-log-item:hover{background-color:#f1f5f9}
.import-log-item.empty-message{color:#9ca3af;font-style:italic;text-align:center;padding:20px}.aps-tab-content.active{display:block}

</style>
 
<script>
  // Tombol close untuk ImportNotifModal
  const importNotifModal = document.getElementById('import-notification');
  const btnClose = document.getElementById('import-notification-close');

  btnClose?.addEventListener('click', () => {
    if(importNotifModal) importNotifModal.style.display = 'none';
  });
</script>

	<?php
		return ob_get_clean();
	}

	/**
	 * Render HTML untuk Controls (Start/Pause/Stop) + Progress Bar + Current Item Info
	 * 
	 * @param int $totalCount Jumlah total item (dari $count)
	 * @return string HTML lengkap (controls + progress)
	 */
	public function renderImportControlsAndProgress(int $totalCount = 0): string
	{
		ob_start();
		?> 
		
		<!-- Controls -->
		<div class="import-controls-wrapper">
			<div class="import-controls">
			<button id="btn-start" class="import-btn primary">
			<span class="dashicons dashicons-controls-play"></span>
			<span class="label"><?php _e('Start Auto Import', TEXT_DOMAIN); ?></span>
			</button>

			<button id="btn-pause" class="import-btn secondary" disabled>
			<span class="dashicons dashicons-controls-pause"></span>
			<span class="label"><?php _e('Pause', TEXT_DOMAIN); ?></span>
			</button>

			<button id="btn-stop" class="import-btn danger" disabled>
			<span class="dashicons dashicons-no-alt"></span>
			<span class="label"><?php _e('Stop', TEXT_DOMAIN); ?></span>
			</button>
			</div>
		</div>	


		<!-- Progress Bar (default disembunyikan) -->
		<div class="progress-container" id="progress-container">
			<div class="progress-header">
			<strong><?php _e('Progress Import', TEXT_DOMAIN); ?></strong>
			<span id="progress-text">0 / <?php echo esc_html($totalCount); ?></span>
			</div>
			<div class="progress-bar-wrapper">
			<div id="progress-bar"></div>
			</div>
			<div id="current-game" style="margin-top:10px; min-height:22px;"></div>
			
			 
			<!-- Import Log - semua pesan error, warning, info dari server -->
			<div class="import-log-wrapper" style="margin-top:10px;">
			<strong><?php _e('Success Logs', TEXT_DOMAIN); ?></strong>
			<ul id="import-log-success" style="list-style:none; padding-left:0; max-height:100px; overflow-y:auto; border:1px solid #ddd; margin-bottom:5px;"></ul>

			<strong><?php _e('Error Logs', TEXT_DOMAIN); ?></strong>
			<ul id="import-log-error" style="list-style:none; padding-left:0; max-height:100px; overflow-y:auto; border:1px solid #ddd; margin-bottom:5px;"></ul>

			<strong><?php _e('Warning Logs', TEXT_DOMAIN); ?></strong>
			<ul id="import-log-warning" style="list-style:none; padding-left:0; max-height:100px; overflow-y:auto; border:1px solid #ddd; margin-bottom:5px;"></ul>

			<strong><?php _e('Info Logs', TEXT_DOMAIN); ?></strong>
			<ul id="import-log-info" style="list-style:none; padding-left:0; max-height:100px; overflow-y:auto; border:1px solid #ddd;"></ul>
			</div>

  
		</div>
			
	<?php
		return ob_get_clean();
	}

	/**
	 * Render pesan sukses "All items imported" setelah proses import selesai
	 * 
	 * @param string $customMessage Pesan tambahan opsional (default kosong)
	 * @return string HTML lengkap untuk div pesan sukses
	 */
	public function renderImportCompleteMessage(string $customMessage = ''): string
	{
		ob_start();
		?>
		<div id="ai-import-complete" style="display:none; margin:40px 0; padding:40px; text-align:center; background:#f6fff8; border:2px dashed #46b450; border-radius:8px;">
		<h2 style="margin:0 0 10px; font-size:26px;"><?php _e('🎉 All items imported', TEXT_DOMAIN); ?></h2>
		<p style="font-size:15px; color:#555;">
		<?php _e('All items were successfully processed.', TEXT_DOMAIN); ?>		
		<?php if (!empty($customMessage)): ?>
		<br><br><strong><?php echo esc_html($customMessage); ?></strong>
		<?php endif; ?>
		</p>
		</div> 
	
		<?php
		return ob_get_clean();
	}

	/**
	 * Render pesan peringatan/info tentang kebutuhan API Key untuk beberapa source
	 * Pesan ini default disembunyikan dan bisa di-toggle via JS
	 *
	 * @param bool $is_visible Default visibility (false = disembunyikan)
	 * @return string HTML pesan info dengan style yang sama
	 */
	public function renderApiKeyWarningMessage(bool $is_visible = false): string
	{
		$display_style = $is_visible ? 'block' : 'none';

		ob_start();
		?>
		<!-- Pesan info yang akan di-toggle -->
		<p id="info_key" class="ai-help-box fancy" style="display: <?php echo esc_attr($display_style); ?>; margin-top: 12px; padding: 12px 16px; border: 1px solid #ffeeba; border-radius: 5px; ">
		  
		<span class="ai-help-title">
			<strong><?php _e('Attention:', TEXT_DOMAIN); ?></strong>
		</span>
		 
			<?php 
			printf(
				/* translators: %1$s, %2$s, %3$s = source names */
				esc_html__('For %1$s, %2$s, and %3$s sources, make sure you have entered a valid API Key or token in the settings so the import process runs smoothly without being blocked by Cloudflare.', TEXT_DOMAIN),
				'APKMODY',
				'GETMODSAPK',
				'LITEAPKS'
			); 
			?> 

		<br>
		<br>

		<span class="ai-help-title">
			<strong>
				<?php 
				printf(
					/* translators: %s = link to API Key settings */
					esc_html__('Add Your Api Key Here → %s', TEXT_DOMAIN),
					'<a href="' . esc_url(admin_url('admin.php?page=_options&tab=20')) . '" target="_blank">' . esc_html__('API Key Settings', TEXT_DOMAIN) . '</a>'
				); 
				?>
			</strong>
		</span>


		</p>
		<?php
		return ob_get_clean();
	}

	/**
	 * Render kotak bantuan berisi contoh URL halaman Apps/Games untuk berbagai source
	 * (kotak info yang muncul sebagai panduan input URL)
	 *
	 * @param bool $is_visible Default visibility (true = tampil, false = disembunyikan)
	 * @return string HTML lengkap untuk kotak bantuan
	 */
	public function renderUrlExamplesHelpBox(bool $is_visible = true): string
	{
		$display = $is_visible ? 'block' : 'none';

		ob_start();
		?>
		<div class="ai-help-box fancy" style="display: <?php echo esc_attr($display); ?>; margin: 20px 0; padding: 16px; border: 1px solid #ffeeba; border-radius: 6px; /* background: #fffef5; color: #856404; */">
		
		<div class="ai-help-title">
			<strong><?php _e('Examples for URL Pages', TEXT_DOMAIN); ?></strong>
		</div>
		
		<p style="margin: 12px 0; font-size: 14px;">
			<?php 
			printf(
				/* translators: %1$s = Apps Page, %2$s = Games Page, %3$s = Single Page */
				esc_html__('Add %1$s or %2$s, %3$s', TEXT_DOMAIN),
				'<strong>' . esc_html__('Apps Page', TEXT_DOMAIN) . '</strong>',
				'<strong>' . esc_html__('Games Page', TEXT_DOMAIN) . '</strong>',
				'<strong>' . esc_html__('not Single Page', TEXT_DOMAIN) . '</strong>'
			); 
			?>
		</p>


		  <ol id="info_5play">
			<li><code>https://5play.org/en/android/games/</code></li>
			<li><code>https://5play.org/en/android/games/page/2/</code></li>
			<li><code>https://5play.org/en/android/apps/</code></li>
			<li><code>https://5play.org/en/android/apps/page/2/</code></li>
		  </ol>

		  <ol id="info_getmodsapk">
			<li><code>https://getmodsapk.com/games/</code></li>
			<li><code>https://getmodsapk.com/games/?page=2</code></li>
			<li><code>https://getmodsapk.com/apps/</code></li>
			<li><code>https://getmodsapk.com/apps/?page=2</code></li>
		  </ol>

		  <ol id="info_apkmody">
			<li><code>https://apkmody.com/games</code></li>
			<li><code>https://apkmody.com/games/page/2</code></li>
			<li><code>https://apkmody.com/apps</code></li>
			<li><code>https://apkmody.com/apps/page/2</code></li>
		  </ol>

		  <ol id="info_liteapks">
			<li><code>https://liteapks.com/games</code></li>
			<li><code>https://liteapks.com/games/page/2</code></li>
			<li><code>https://liteapks.com/apps</code></li>
			<li><code>https://liteapks.com/apps/page/2</code></li>
		  </ol>
		</div>
		<?php

		return ob_get_clean();
	}

	/**
	 * Render tabbed help section: How to Use, How to Reset, Donation
	 * Persis sama dengan HTML yang diberikan, tanpa perubahan apapun
	 *
	 * @return string HTML lengkap untuk tab help + donation
	 */
	public function renderHelpTabsSection(): string
	{
		ob_start();
		?>
		<div class="ai-tabs-wrapper">
		  <div class="ai-tabs-nav">
		  
			<button class="ai-tab-btn active" data-tab="ai-tab-usage">
				📘 <?php _e('How to Use', TEXT_DOMAIN); ?>
			</button>
			<button class="ai-tab-btn" data-tab="ai-tab-donasi">
				❤️ <?php _e('Supports', TEXT_DOMAIN); ?>
			</button>

		  </div>

		  <div class="ai-tabs-content">
			<!-- ================= TAB: HOW TO USE ================= -->
			<div id="ai-tab-usage" class="ai-tab-panel active">
			  <div class="postbox ai-how-to-use">
				<div class="ai-accordion">
				
				  <div class="ai-acc-item">
					<button class="ai-acc-title">
					  ⚙️ Configure Auto Importer Settings
					  <span class="ai-acc-icon">+</span>
					</button>
					<div class="ai-acc-content">
					  <p>
						Select the <strong>Source</strong> and enter the correct
						<strong>URL Pages</strong> Apps or Games, based on the examples provided.</p>
						<p>Click <strong>Save Settings</strong> before starting the import.
					  </p>
					</div>
				  </div>

				  <div class="ai-acc-item">
					<button class="ai-acc-title">
					  ▶️ Start Auto Import
					  <span class="ai-acc-icon">+</span>
					</button>
					<div class="ai-acc-content">
					  <p>
						Click <strong>Start Auto Import</strong> to begin the automatic import process.</p>
						<p>Settings will be locked while the importer is running.</p>
						<p style="font-size:1rem;">Do not <strong>close</strong> or <strong>refresh</strong> the page while the <strong>import is running</strong>.
					  </p>
					</div>
				  </div> 

				  <div class="ai-acc-item">
					<button class="ai-acc-title">
					  ⚠️ Manual Submit (Auto Post)
					  <span class="ai-acc-icon">+</span>
					</button>
					<div class="ai-acc-content">
					  <p>
						If an item fails or encounters a connection error,
						a <strong>Submit Manual</strong> button will appear automatically.</p>
						<p>Use it to import the item manually.
					  </p>
					</div>
				  </div>

				  <div class="ai-acc-item">
					<button class="ai-acc-title">
					  ⚠️ Manual Submit (Single URL)
					  <span class="ai-acc-icon">+</span>
					</button>
					<div class="ai-acc-content">
					  <p>
						<strong>Manual Submit (Single URL) Box</strong> allows to submit a <strong>single URL</strong> for scraping and importing app or game information into post.</p>
						<p>It supports detecting the source automatically from the URL and displays relevant notices for restricted sources or API requirements. </p>
						<p>The submitted data is then displayed as a card in the interface.
					  </p>
					</div>
				  </div>

				  
				  <div class="ai-acc-item">
				  <button class="ai-acc-title">
					⚠️ API Key Requirement
					<span class="ai-acc-icon">+</span>
				  </button>
				  <div class="ai-acc-content">
					<p>
					  <strong>For the following sources:</strong>
					</p>
					
					<ol>					 
						<li>• APKMODY</li>
						<li>• GETMODSAPK</li>
						<li>• LITEAPKS</li>
					</ol>					

					<p>
					  You must configure a valid <strong>API Key or access token</strong> in the plugin settings.
					  These websites are protected by Cloudflare or similar security systems.
					  Without a valid API Key, the import or scraping process may fail, be blocked,
					  or return incomplete data.
					</p>

					<p><strong>Why This Is Required</strong></p>
					<ol>
					  <li>Prevents Cloudflare rate-limiting and bot protection blocks</li>
					  <li>Ensures stable and consistent scraping results</li>
					  <li>Reduces failed imports and timeout errors</li>
					</ol>

					<p><strong>What Happens Without an API Key</strong></p>
					<ol>
					  <li>The manual submit process will still run</li>
					  <li>However, the import may fail or return empty data</li>
					  <li>You may see warnings, partial results, or scraping errors</li>
					</ol>

					<p><strong>How to Add Your API Key</strong></p>
					<ol>
					  <li>Go to the <strong>API Key Settings</strong> page in the themes admin panel</li>
					  <li>Enter your valid API Key or token for the corresponding source</li>
					  <li>Save the settings before running a manual or automatic import</li>
					</ol>

					<p>
					  👉 <strong>
						<a href="<?php echo admin_url(); ?>admin.php?page=_options&tab=20" target="_blank">
						  Add Your API Key Here → API Key Settings
						</a>
					  </strong>
					</p>
				  </div>
				</div>


				  <div class="ai-acc-item">
					<button class="ai-acc-title">
					  🎉 Import Completed
					  <span class="ai-acc-icon">+</span>
					</button>
					<div class="ai-acc-content">
					  <p>
						Once all items are processed, the table will be hidden
						and the importer will reset automatically.
					  </p>
					</div>
				  </div>
 

				<div class="ai-acc-item">
				  <button class="ai-acc-title">
					2️⃣  Reset - Trigger By Url Link 
					<span class="ai-acc-icon">+</span>
				  </button>
				  <div class="ai-acc-content">
					<p>
					  Designed for critical situations such as corrupted settings,
					  importer crashes, broken admin UI, or Api Key or Token Expired.
					</p>
					<ul>
					  <li>Deletes option completely</li>
					  <li>No form submission required</li>
					  <li>Admin-only access</li>
					</ul>
					<p><strong>Trigger URL:</strong></p>
					<pre><code><?php echo admin_url(); ?>admin.php?page=sc-auto-post&ai_force_reset=1</code></pre> 
					<div class="ai-doc-notice warning">
					  <strong>Warning:</strong> Use only when normal reset is not possible.
					</div>
				  </div>
				</div>

				<div class="ai-acc-item">
				  <button class="ai-acc-title">
					3️⃣  Reset - 🚨 Admin Bar
					<span class="ai-acc-icon">+</span>
				  </button>
				  <div class="ai-acc-content">
					<p>
					  Adds a quick <strong>🚨 Reset Importer</strong> shortcut to the WordPress Admin Bar.
					</p>
					<ul>
					  <li>Visible only to administrators</li>
					  <li>Confirmation dialog before reset</li>
					  <li>Direct access to emergency reset</li>
					</ul> 
				  </div>
				</div>
				
				</div>

				<p class="ai-note" style="font-size: 1.2rem; line-height: 1.5; margin: 10px 1em;">
				  Do not <strong>close</strong> or <strong>refresh</strong> the page while the <strong>import is running</strong>.
				</p>
			  </div>
			</div>

			 

			<!-- ================= TAB: DONASI ================= -->
			<div id="ai-tab-donasi" class="ai-tab-panel">
			  <div class="ai-donation-box">
				<h3>❤️ Support exthem.es</h3>
				<p>
				  If this theme helps you save time and grow your website,
				  please consider supporting development through a donation.
				</p>
				<ul>
				  <li>☕ Help maintain updates</li>
				  <li>🚀 Fund new features</li>
				  <li>🛠 Faster bug fixes</li>
				</ul>

				<!-- PayPal -->
				<a href="https://paypal.me/exthemesdevs" target="_blank" class="ai-donate-btn">
				  <img alt="PayPal" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjwhRE9DVFlQRSBzdmcgIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICAnaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkJz48c3ZnIGhlaWdodD0iNTEycHgiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB3aWR0aD0iNTEycHgiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxnIGlkPSJfeDMyXzUwLXBheXBhbCI+PGc+PHBhdGggZD0iTTI1MC41ODUsMjcxLjg3NGM2OC41NjYtMC44MTEsMTIwLjI5OS0yOC4wOTcsMTQyLjEwNi05MS41OTMgICAgYzIxLjkxMS02MS42NzEsMTYuMzMyLTExOC42NzYtNDQuNjMtMTQyLjMxMWMtMzkuNDU3LTE1LjMxNi01Mi40NDEtMTEuNTYzLTIwNi45MjMtMTEuNTYzYy0xMC4wNDIsMC0xOC43NjUsNy40MDUtMjAuMjg4LDE3LjE0MiAgICBMNjEuNDEyLDQyMC43NzhjLTEuMDE0LDcuNDA0LDQuNTY0LDE0LjA5OSwxMi4yNzIsMTQuMDk5aDc1LjY2OWMyLjAyOSwwLDIuNzM4LTAuNzA4LDMuMDQzLTIuNTM0ICAgIGM0LjE1OC0yNS42NjQsMTguMjU5LTExNi40NDcsMjEuODA4LTEzNS45MjJDMTgwLjA4OSwyNjQuNzc0LDIwNi41NjMsMjcyLjU4NiwyNTAuNTg1LDI3MS44NzR6IiBzdHlsZT0iZmlsbDojMDAyRDhBOyIvPjxwYXRoIGQ9Ik00MjMuNDI3LDE1MC40NmMtMS44MjYtMS4zMTktMi41MzYtMS44MjctMy4wNDMsMS4zMTdjLTIuMDI5LDExLjU2NS01LjE3MywyMi44MjMtOC45MjcsMzQuMDgzICAgIEMzNzAuOTg1LDMwMS4yOSwyNTguOCwyOTEuMjQ5LDIwNC4wMjYsMjkxLjI0OWMtNi4xODgsMC0xMC4yNDUsMy4zNDgtMTEuMDU3LDkuNTM0ICAgIGMtMjIuOTIzLDE0Mi40MTEtMjcuNDg4LDE3Mi4xMzEtMjcuNDg4LDE3Mi4xMzFjLTEuMDE1LDcuMjAyLDMuNTUsMTMuMDg1LDEwLjc1MiwxMy4wODVoNjQuNDFjOC43MjMsMCwxNS45MjUtNi4zOTEsMTcuNjUtMTUuMTEyICAgIGMwLjcwOS01LjQ3OS0xLjExNSw2LjE4NywxNC42MDYtOTIuNjA5YzQuNjY1LTIyLjMxNCwxNC41MDQtMTkuOTgsMjkuNzE5LTE5Ljk4YzcyLjAxOSwwLDEyOC4yMTEtMjkuMjE0LDE0NC45NDgtMTEzLjkxICAgIEM0NTQuMTYxLDIwOS4wODgsNDUyLjIzNCwxNzEuOTYzLDQyMy40MjcsMTUwLjQ2eiIgc3R5bGU9ImZpbGw6IzAxOUJFMTsiLz48L2c+PC9nPjxnIGlkPSJMYXllcl8xIi8+PC9zdmc+">
				  Donate via PayPal
				</a>
				<hr>

				<!-- Bitcoin -->
				<div class="ai-crypto-box">
				  <strong>₿ Donate via Bitcoin</strong>
				  <textarea class="aps-textarea ai-autoheight" readonly onclick="this.select()" spellcheck="false">AK4yetqZNDYyQdLKZVHqRh9HpdxdAEhyy</textarea>
				</div>

				<!-- USDT -->
				<div class="ai-crypto-box">
				  <strong>🪙 Donate via Tether (USDT – TRC20)</strong>
				  <textarea class="aps-textarea ai-autoheight" readonly onclick="this.select()" spellcheck="false">TSP7i8XuRvbQQ5VfhDC2EwL8XMucvU4Qr1</textarea>
				</div>

				<!-- Ethereum -->
				<div class="ai-crypto-box">
				  <strong>🪙 Donate via Ethereum (ERC-20 / ETH)</strong>
				  <textarea class="aps-textarea ai-autoheight" readonly onclick="this.select()" spellcheck="false">0x94fcbd06a3f700898ba750fc942d726b86da1f5f</textarea>
				</div>

				<p class="ai-donate-note">
				  <em>Thank you for your support ❤️</em>
				</p>
			  </div>
			</div>
		  </div>
		</div>
		<?php

		return ob_get_clean();
	}

	/**
	 * Render form pengaturan Auto Importer lengkap (Source, URL Pages, Save & Reset)
	 * Persis sama dengan HTML yang diberikan, tanpa perubahan apapun pada struktur, class, ID, teks, atau gaya
	 *
	 * @param array $settings       Array pengaturan saat ini
	 * @param array $default_sources Daftar source default untuk dropdown
	 * @return string HTML lengkap form settings
	 */
	public function renderImporterSettingsForm(array $settings, array $default_sources): string
	{
		ob_start();
		?>
		<?php
		echo $this->renderApiKeyWarningMessage(); // true display: block
		?>
		<form method="post" action="options.php">
		  <?php settings_fields('auto_importer_groups'); ?>
		  <table class="form-table">
			<!-- SOURCE -->
			<tr>
			  <th scope="row"><?php _e('Source', TEXT_DOMAIN); ?></th>

			  <td>
				<select name="auto_importer_settingss[source]" id="source-select">
				  <?php foreach ($default_sources as $k => $v): ?>
					<option value="<?php echo esc_attr($k); ?>" <?php selected($settings['source'], $k); ?>>
					  <?php echo strtoupper($k); ?>
					</option>
				  <?php endforeach; ?>
				</select>
			  </td>
			</tr>
			<!-- BASE URL -->
			<tr id="base_url">
			  <th scope="row"><?php _e('URL Pages', TEXT_DOMAIN); ?></th>

			  <td>
				<input id="base_domain_url" type="url" name="auto_importer_settingss[base_url]" value="<?php echo esc_attr($settings['base_url']); ?>" class="regular-text code" placeholder="https://5play.org/en/android/games/" />
			  </td>
			</tr>
		  </table>
		  <?php
		  // Default disembunyikan
		  echo $this->renderUrlExamplesHelpBox();
		  ?>
		  <div style="display:flex; gap:10px; align-items:center;">
			<button type="submit"
					name="submit"
					id="submit"
					class="button button-primary">
			  <?php _e('Save Settings', TEXT_DOMAIN); ?>
			</button>
		  </form>
		  <form method="post" style="margin:0;">
			<?php wp_nonce_field('auto_importer_reset_action', 'auto_importer_reset_nonce'); ?>
			<input type="hidden" name="auto_importer_reset_settings" value="1">
			<button type="submit" class="button" onclick="return confirm('Reset importer settings to default?');"> <?php _e('Reset Settings', TEXT_DOMAIN); ?> </button>
		  </form>
		  </div>
		<?php
		return ob_get_clean();
	}

	/**
	 * Render kotak pengaturan utama "Importer Settings" dengan postbox style
	 * Persis sama dengan HTML yang diberikan, tanpa perubahan apapun pada struktur, class, teks, atau gaya
	 *
	 * @param array $settings       Array pengaturan saat ini
	 * @param array $default_sources Daftar source default untuk dropdown
	 * @return string HTML lengkap untuk kotak settings
	 */
	public function renderImporterSettingsPostbox(array $settings, array $default_sources): string
	{
		ob_start();
		?>
		<div class="postbox ai-settings-box">
			<h2 class="hndle ai-center-title">
				<span>🚀 <?php _e('Auto Importer Settings', TEXT_DOMAIN); ?></span>
			</h2>

		  <div class="inside">
			<?php
			// Contoh penggunaan di halaman admin
			echo $this->renderImporterSettingsForm($settings, $default_sources);
			?>
		  </div>
		</div>
		<?php
		return ob_get_clean();
	}

	public function render_search_submit_box()
	{
		ob_start();
        ?>

<div class="postbox ai-settings-box ai-manual-box">
	<div class="inside">
	

	<!-- loading overlay -->
	<div id="manual-loading-overlay" class="import-loading-overlay" style="display:none;">
	<div class="import-spinner"></div>
	<p><?php _e('Processing import… Please wait', TEXT_DOMAIN); ?></p>
	</div>

	<h2 class="hndle ai-center-title">
		<span><?php _e('Live Search Google PlayStore', TEXT_DOMAIN); ?></span>
	</h2>

	<p class="app-description">
		<?php 
		printf(
			/* translators: Bold part = Search Apps By Title */
			esc_html__('This tool allows you to %s and instantly display results from Google Play', TEXT_DOMAIN),
			'<strong>' . esc_html__('Search Apps By Title', TEXT_DOMAIN) . '</strong>'
		); 
		?>
	</p>


	<div class="how-to-use-box">
		<button class="how-to-use-toggle" type="button">
			📘 <?php _e('How to Use', TEXT_DOMAIN); ?>
			<span class="panah">▾</span>
		</button>

		<div class="how-to-use-content"> 

		<ol class="app-search-instructions">
			<li>
				<?php _e('Type the name of the app in the input field. You do not need to press any button; results will appear automatically while typing.', TEXT_DOMAIN); ?>
			</li>
			<li>
				<?php 
				printf(
					/* translators: Bold part = AppID, version, poster, and store link */
					esc_html__('Results include %s.', TEXT_DOMAIN),
					'<strong>' . esc_html__('AppID, version, poster, and link', TEXT_DOMAIN) . '</strong>'
				); 
				?>
			</li>
			<li>
				<?php 
				printf(
					/* translators: Bold part = Manual Submit (Single URL) */
					esc_html__('The result link will automatically populate the %s field.', TEXT_DOMAIN),
					'<strong>' . esc_html__('Manual Submit (Single URL)', TEXT_DOMAIN) . '</strong>'
				); 
				?>
			</li>
			<li>
				<?php 
				printf(
					/* translators: Bold parts = 🚀 Submit Manual, Manual Submit (Single URL) */
					esc_html__('You can click %1$s directly, or copy the link and paste it into %2$s before clicking %1$s.', TEXT_DOMAIN),
					'<strong>🚀 ' . esc_html__('Submit Manual', TEXT_DOMAIN) . '</strong>',
					'<strong>' . esc_html__('Manual Submit (Single URL)', TEXT_DOMAIN) . '</strong>'
				); 
				?>
			</li>

		</ol>
		</div>
	</div>

	<div class="ai-input-group floating-label">
		<?php wp_nonce_field('search_playstore_ajax', 'search_playstore_nonce'); ?>

		<input 
			type="text" 
			name="app_title" 
			id="app_title" 
			placeholder=" " 
			autocomplete="off"
		>
		<label for="app_title"><?php _e('Enter App Title', TEXT_DOMAIN); ?></label>

	</div>


	<div id="search-playstore-result" class="card-list" style="margin-top:15px;"></div>
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', () => {

    const inputTitle = document.getElementById('app_title');          // input untuk judul app
    const urlField = document.getElementById('manual-submit-url');    // input URL yang akan diisi
    const resultBox = document.getElementById('search-playstore-result'); // area hasil
    const noticeBox = document.getElementById('manual-notices');      // notice area
	
	const overlay = document.getElementById('manual-loading-overlay');
    const nonce = document.querySelector('#search_playstore_nonce')?.value || '';
    let timeout = null;

    inputTitle.addEventListener('input', function() {
        const query = this.value.trim();

        if (!query) {
            resultBox.innerHTML = '';
            noticeBox.innerHTML = '';
            urlField.value = '';
            overlay.style.display = 'none'; 
            return;
        }

        clearTimeout(timeout);
        timeout = setTimeout(async () => {

            noticeBox.innerHTML = 'Searching...';
            resultBox.innerHTML = '';
            overlay.style.display = 'flex'; 

            try {
                const formData = new FormData();
                formData.append('action', 'manual_search_app');
                formData.append('app_title', query);
                formData.append('manual_search_submit_nonce', nonce);

                const response = await fetch('<?php echo admin_url("admin-ajax.php"); ?>', {
                    method: 'POST',
                    body: formData
                });

                const res = await response.json();
                noticeBox.innerHTML = '';

                overlay.style.display = 'none'; 
				
                if (res.success) {
                    const data = res.data;

                    // Isi field URL dengan link dari hasil
                    urlField.value = data.link;

                    // Buat kartu hasil
                    const cardHtml = `
<div class="card-item" style="padding:10px; margin-bottom:10px; display:flex; gap:10px; border-radius:6px;">
    <div style="flex-shrink:0;">
        <img src="${data.poster}" alt="${data.title}" style="width:80px; height:80px; object-fit:cover; border-radius:4px;">
    </div>
    <div style="flex:1;">
        <h4 style="margin:0 0 5px;">${data.title} ${data.version}</h4>  
        <p style="margin:0; font-size:0.9rem;">${data.summary}</p>
        <p style="margin:0; font-size:0.9rem;">Link: <a href="${data.link}" target="_blank">${data.appid}</a></p>
    </div>
</div>`;

                    resultBox.innerHTML = cardHtml;

                } else {
                    resultBox.innerHTML = `<span style="color:#ff4d4d;">${res.data}</span>`;
                    urlField.value = '';
                }

            } catch (err) {
                overlay.style.display = 'none'; 
                resultBox.innerHTML = `<span style="color:#ff4d4d;">ERROR: ${err.message}</span>`;
                urlField.value = '';
            }

        }, 500); // delay 500ms sebelum trigger AJAX
    });

});
</script>
 
<script>
document.addEventListener('DOMContentLoaded', () => {
    const toggle = document.querySelector('.how-to-use-toggle');
    const box = document.querySelector('.how-to-use-box');

    toggle.addEventListener('click', () => {
        box.classList.toggle('active');
    });
});
</script>

<style> 
.floating-label{position:relative;max-width:600px;margin-bottom:20px;font-family:'Segoe UI',Tahoma,sans-serif}
.floating-label input{width:100%;padding:14px 12px;font-size:16px;border:1px solid #d1d5db;border-radius:10px;background:#ffffff;color:#111827;outline:none;transition:border-color 0.25s ease,box-shadow 0.25s ease}
.floating-label input:focus{border-color:#2271b1;box-shadow:0 0 0 3px rgba(0,188,212,0.15)}
.floating-label label{position:absolute;top:50%;left:12px;transform:translateY(-50%);font-size:15px;color:#9ca3af;pointer-events:none;background:#ffffff;padding:0 6px;transition:all 0.25s ease}
.floating-label input:focus + label,.floating-label input:not(:placeholder-shown) + label{top:-6px;font-size:12px;color:#2271b1}.aps-tab-content.active{display:block}
.how-to-use-box{border:1px solid #e5e7eb;border-radius:12px;background:#ffffff;max-width:900px;margin-bottom:20px}
.how-to-use-toggle{width:100%;background:none;border:none;padding:14px 18px;font-size:16px;font-weight:600;color:#111827;display:flex;justify-content:space-between;align-items:center;cursor:pointer}
.how-to-use-toggle:hover{background:#f9fafb}
.how-to-use-toggle .panah{transition:transform 0.3s ease;font-size:18px}
.how-to-use-content{max-height:0;overflow:hidden;transition:max-height 0.35s ease;padding:0 18px}
.how-to-use-content h3{margin-top:10px;margin-bottom:12px}
.how-to-use-box.active .how-to-use-content{max-height:500px;padding-bottom:18px}
.how-to-use-box.active .panah{transform:rotate(180deg)}.aps-tab-content.active{display:block}
.app-search-instructions{list-style:none;margin:0;border-radius:12px;border:1px solid #ccc;color:#333;font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif;font-size:1rem;line-height:1.6;max-width:800px;background:transparent}
.app-search-instructions li{position:relative;margin-bottom:15px;padding:12px 15px 12px 30px;border-radius:8px;transition:all 0.3s ease;background:#f9f9f9;border:1px solid #eee}
.app-search-instructions li::before{content:'•';position:absolute;left:10px;top:50%;transform:translateY(-50%);color:#2271b1;font-weight:bold;font-size:1.2rem}
.app-search-instructions li:hover{background:#e0f0ff;box-shadow:0 4px 10px rgba(0,0,0,0.1)}
.app-search-instructions li strong{color:#2271b1;font-weight:600}
.ai-input-group{display:flex;flex-direction:column;margin-bottom:20px;max-width:500px;font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif}
.ai-input-group label{color:#333333;font-weight:600;font-size:1rem;margin-bottom:6px;transition:color 0.3s ease}
.ai-input-group label:hover{color:#007bff}
.ai-input-group input[type="text"],.ai-input-group input[type="url"]{padding:12px 15px;border-radius:8px;border:1px solid #ccc;background:#ffffff;color:#333333;font-size:1rem;outline:none;transition:all 0.3s ease}
.ai-input-group input[type="text"]:focus,.ai-input-group input[type="url"]:focus{border-color:#007bff;box-shadow:0 0 10px rgba(0,123,255,0.2)}
.ai-input-group input::placeholder{color:#aaaaaa;font-style:italic}
.app-description{color:#333333;font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif;font-size:1rem;line-height:1.6;max-width:700px;margin:10px 0 20px 0;padding:10px 15px;background:#f9f9f9;border-left:4px solid #007bff;border-radius:6px;transition:background 0.3s ease}
.app-description:hover{background:#f1f1f1}
.app-description strong{color:#007bff}
.aps-tab-content.active{display:block}
</style>

		<?php
		return ob_get_clean();
	}

	public function render_search_all_form_submit_box()
	{
		ob_start();
        ?>

<div class="postbox ai-settings-box ai-manual-box">
	<div class="inside">
	

	<!-- loading overlay -->
	<div id="search-loading-overlay" class="import-loading-overlay" style="display:none;">
	<div class="import-spinner"></div>
	<p><?php _e('Please wait', TEXT_DOMAIN); ?></p>

	</div>
	
	<h2 class="hndle ai-center-title">
	<span><?php _e('Live Search Google PlayStore', TEXT_DOMAIN); ?></span>

	</h2>
		
	<p class="app-description">
		<?php 
		printf(
			/* translators: Bold part = Search Apps By Title */
			esc_html__('This form allows you to %s and instantly display results from Google Play', TEXT_DOMAIN),
			'<strong>' . esc_html__('Search Apps By Title', TEXT_DOMAIN) . '</strong>'
		); 
		?>
	</p>



	<div class="how-to-use-box">
	
		<button class="how-to-use-toggle" type="button">
			📘 <?php _e('How to Use', TEXT_DOMAIN); ?>
			<span class="panah">▾</span>
		</button>

		<div class="how-to-use-content"> 

		<ol class="app-search-instructions">
			<li>
				<?php _e('Type the name of the app in the input field. You do not need to press any button; results will appear automatically while typing.', TEXT_DOMAIN); ?>
			</li>
			<li>
				<?php 
				printf(
					/* translators: Bold part = AppID, version, poster, and store link */
					esc_html__('Results include %s.', TEXT_DOMAIN),
					'<strong>' . esc_html__('AppID, version, poster, and store link', TEXT_DOMAIN) . '</strong>'
				); 
				?>
			</li>
			<li>
				<?php 
				printf(
					/* translators: Bold part = Manual Submit (Single URL) */
					esc_html__('The result link will automatically populate the %s field.', TEXT_DOMAIN),
					'<strong>' . esc_html__('Manual Submit (Single URL)', TEXT_DOMAIN) . '</strong>'
				); 
				?>
			</li>
			<li>
				<?php 
				printf(
					/* translators: Bold parts = 🚀 Submit Manual, Manual Submit (Single URL) */
					esc_html__('You can click %1$s directly, or copy the link and paste it into %2$s before clicking %1$s.', TEXT_DOMAIN),
					'<strong>🚀 ' . esc_html__('Submit Manual', TEXT_DOMAIN) . '</strong>',
					'<strong>' . esc_html__('Manual Submit (Single URL)', TEXT_DOMAIN) . '</strong>'
				); 
				?>
			</li>
		</ol>


		</div>
	</div>

	<div class="ai-input-group floating-label has-clear">
		<input 
			type="text" 
			name="app_title" 
			id="sc-search-input" 
			placeholder=" " 
			autocomplete="off"
		>
		<label for="sc-search-input"><?php _e('Search App or Games...', TEXT_DOMAIN); ?></label>
		<button type="button" class="clear-btn" aria-label="Clear">&times;</button>
	</div>

	<div id="search-playstore-result" class="card-list" style="margin-top:15px;"></div>
	</div>
</div>


<script>
jQuery(document).ready(function($){

    // --- Overlay DOM ---
    const overlay = document.getElementById('search-loading-overlay');

    function showManualOverlay() {
        if (overlay) overlay.style.display = 'flex';
    }

    function hideManualOverlay() {
        if (overlay) overlay.style.display = 'none';
    }

    // --- Live Search ---
    let timer = null;
    let delay = 500;

    $('#sc-search-input').on('keyup', function () {
        clearTimeout(timer);

        let keyword = $(this).val().trim();

        // Clear results if < 3 chars
        if (keyword.length < 3) {
            $('#search-playstore-result').html('');
            hideManualOverlay();
            return;
        }

        timer = setTimeout(function(){

            showManualOverlay();

            $.ajax({
                url: ajaxurl,
                type: 'POST',
                dataType: 'json',
                data: {
                    action: 'manual_search_all_app',
                    keyword: keyword
                },
                success: function(res){

                    if (!res.success || !res.data.length) {
                        $('#search-playstore-result').html(
                            '<div class="ai-empty"><?php _e("No app found", TEXT_DOMAIN); ?></div>'
                        );
                        return;
                    }


                    let html = '';

                    res.data.forEach(function(app, index){
                        html += `
                        <div class="card-item" style="padding:10px; margin-bottom:10px; display:flex; gap:10px; border-radius:6px;">
                            <div style="flex-shrink:0; text-align:center;">
                                <img src="${app.poster}" alt="${app.appname}" style="width:80px; height:80px; object-fit:cover; border-radius:4px;">
                                <br>
                                <button type="button" class="ai-submit-btn-link" 
                                    data-appid="${app.appid}" 
                                    data-appname="${app.appname}" 
                                    data-link="${app.link}" 
                                    style="margin-top:5px; padding:6px 12px; background:#2271b1; color:#fff; border:none; border-radius:4px; cursor:pointer;  max-width: 90px;">
                                    <?php _e("Copy Link", TEXT_DOMAIN); ?>
                                </button>
                            </div>
                            <div style="flex:1;">
                                <h4 style="margin:0 0 5px;">${app.appname}</h4>  
                                <p style="margin:0; font-size:0.9rem;">Version : ${app.version} = Update : ${app.update}</p> 
                                <p style="margin:0; font-size:0.9rem;">${app.developer} - ${app.category}</p>  
                                <p style="margin:0; font-size:0.9rem;">${app.summary}</p>
                            </div>
                        </div>`;
                    });

                    $('#search-playstore-result').html(html);

                    // Tambahkan click event untuk tombol submit
                    $('.ai-submit-btn-link').on('click', function(){
                        let link = $(this).data('link');

                        // Masukkan ke input manual submit
                        $('#manual-submit-url').val(link);

                        // Opsional: fokus ke input
                        $('#manual-submit-url').focus();
                    });
                },
                error: function(){
                    $('#search-playstore-result').html(
                        '<div class="ai-error">Request failed</div>'
                    );
                },
                complete: function(){
                    hideManualOverlay();
                }
            });

        }, delay);
    });
});
</script>

<script>
document.addEventListener('DOMContentLoaded', () => {
    const toggle = document.querySelector('.how-to-use-toggle');
    const box = document.querySelector('.how-to-use-box');

    toggle.addEventListener('click', () => {
        box.classList.toggle('active');
    });
});


</script>

<script>
document.addEventListener('DOMContentLoaded', () => {
    const input = document.getElementById('sc-search-input');
    const clearBtn = input.parentElement.querySelector('.clear-btn');

    input.addEventListener('input', () => {
        clearBtn.style.display = input.value ? 'flex' : 'none';
    });

    clearBtn.addEventListener('click', () => {
        // kosongkan input
        input.value = '';
        input.focus();

        // sembunyikan tombol clear
        clearBtn.style.display = 'none';

        // HENTIKAN timer debounce (jQuery live search)
        if (window.timer) {
            clearTimeout(window.timer);
        }

        // Bersihkan hasil pencarian
        jQuery('#search-playstore-result').html('');

        // Sembunyikan overlay loading
        const overlay = document.getElementById('search-loading-overlay');
        if (overlay) overlay.style.display = 'none';

        // trigger ulang input event (floating label sync)
        input.dispatchEvent(new Event('input'));
    });
});
</script>

<style> 
.has-clear{position:relative}
.has-clear input{padding-right:42px}
.clear-btn{position:absolute;top:50%;right:12px;transform:translateY(-50%);border:none;background:red;color:white;width:22px;height:22px;border-radius:50%;cursor:pointer;display:none;align-items:center;justify-content:center;transition:all 0.2s ease}
.clear-btn:hover{background:#2271b1;color:#ffffff}.aps-tab-content.active{display:block}
.floating-label{position:relative;max-width:600px;margin-bottom:20px;font-family:'Segoe UI',Tahoma,sans-serif}
.floating-label input{width:100%;padding:14px 12px;font-size:16px;border:1px solid #d1d5db;border-radius:10px;background:#ffffff;color:#111827;outline:none;transition:border-color 0.25s ease,box-shadow 0.25s ease}
.floating-label input:focus{border-color:#2271b1;box-shadow:0 0 0 3px rgba(0,188,212,0.15)}
.floating-label label{position:absolute;top:50%;left:12px;transform:translateY(-50%);font-size:15px;color:#9ca3af;pointer-events:none;background:#ffffff;padding:0 6px;transition:all 0.25s ease}
.floating-label input:focus + label,.floating-label input:not(:placeholder-shown) + label{top:-6px;font-size:12px;color:#2271b1}.aps-tab-content.active{display:block}
.how-to-use-box{border:1px solid #e5e7eb;border-radius:12px;background:#ffffff;max-width:900px;margin-bottom:20px}
.how-to-use-toggle{width:100%;background:none;border:none;padding:14px 18px;font-size:16px;font-weight:600;color:#111827;display:flex;justify-content:space-between;align-items:center;cursor:pointer}
.how-to-use-toggle:hover{background:#f9fafb}
.how-to-use-toggle .panah{transition:transform 0.3s ease;font-size:18px}
.how-to-use-content{max-height:0;overflow:hidden;transition:max-height 0.35s ease;padding:0 18px}
.how-to-use-content h3{margin-top:10px;margin-bottom:12px}
.how-to-use-box.active .how-to-use-content{max-height:500px;padding-bottom:18px}
.how-to-use-box.active .panah{transform:rotate(180deg)}.aps-tab-content.active{display:block}
.app-search-instructions{list-style:none;margin:0;border-radius:12px;border:1px solid #ccc;color:#333;font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif;font-size:1rem;line-height:1.6;max-width:800px;background:transparent}
.app-search-instructions li{position:relative;margin-bottom:15px;padding:12px 15px 12px 30px;border-radius:8px;transition:all 0.3s ease;background:#f9f9f9;border:1px solid #eee}
.app-search-instructions li::before{content:'•';position:absolute;left:10px;top:50%;transform:translateY(-50%);color:#2271b1;font-weight:bold;font-size:1.2rem}
.app-search-instructions li:hover{background:#e0f0ff;box-shadow:0 4px 10px rgba(0,0,0,0.1)}
.app-search-instructions li strong{color:#2271b1;font-weight:600}
.ai-input-group{display:flex;flex-direction:column;margin-bottom:20px;max-width:500px;font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif}
.ai-input-group label{color:#333333;font-weight:600;font-size:1rem;margin-bottom:6px;transition:color 0.3s ease}
.ai-input-group label:hover{color:#007bff}
.ai-input-group input[type="text"],.ai-input-group input[type="url"]{padding:12px 15px;border-radius:8px;border:1px solid #ccc;background:#ffffff;color:#333333;font-size:1rem;outline:none;transition:all 0.3s ease}
.ai-input-group input[type="text"]:focus,.ai-input-group input[type="url"]:focus{border-color:#007bff;box-shadow:0 0 10px rgba(0,123,255,0.2)}
.ai-input-group input::placeholder{color:#aaaaaa;font-style:italic}
.app-description{color:#333333;font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif;font-size:1rem;line-height:1.6;max-width:700px;margin:10px 0 20px 0;padding:10px 15px;background:#f9f9f9;border-left:4px solid #007bff;border-radius:6px;transition:background 0.3s ease}
.app-description:hover{background:#f1f1f1}
.app-description strong{color:#007bff}
.aps-tab-content.active{display:block}
</style>

		<?php
		return ob_get_clean();
	}

	public function render_manual_submit_box(array $settings): string
	{
        // Ambil settings auto importer (untuk JS)
        $settings = get_option('auto_importer_settingss', [
            'source'   => '5play',
            'base_url' => 'https://5play.org/en/android/games/',
        ]);
		ob_start();
        ?>
		
<div class="postbox ai-settings-box ai-manual-box">

	<div class="inside">
  
	<!-- loading overlay -->
	<div id="manual-loading-overlay" class="import-loading-overlay" style="display:none;">
	<div class="import-spinner"></div>
	<p><?php _e('Processing import… Please wait', TEXT_DOMAIN); ?></p>
	</div>
	
	<div class="manual-submit-box">
	
	<h2 class="hndle ai-center-title">
	<span><?php _e('Manual Submit (Single URL)', TEXT_DOMAIN); ?></span>
	</h2>
	
	<!-- Notice -->
	<div id="manual-notices" class="ai-notice-area"></div>
	
	<!-- Detected info -->
	<div id="manual-detected-info" class="ai-detected-info">
		<strong><?php _e('Detected:', TEXT_DOMAIN); ?></strong>
		<span id="manual-detected-host">-</span>
		<span class="ai-separator">/</span>
		<strong><?php _e('Source:', TEXT_DOMAIN); ?></strong>
		<span id="manual-detected-source" class="ai-source-badge">-</span>
		
		<small class="ai-help-text">
		<?php _e('The source will be detected automatically based on the domain.', TEXT_DOMAIN); ?>
		</small>		
	</div>
	
	<div class="example-collapse-box">
		<button class="example-collapse-toggle" type="button">
			📎 <?php _e('Example Links', TEXT_DOMAIN); ?>
			<span class="panah">▾</span>
		</button>

		<div class="example-collapse-content">
			<p class="app-description">
				<?php _e('Below are examples of supported URLs:', TEXT_DOMAIN); ?>
			</p>

			<ol class="app-search-instructions">
				<li>https://play.google.com/store/apps/details?id=com.roblox.client</li>
				<li>https://5play.org/en/11448-minecraft-mod.html</li>
				<li>https://apkmody.com/apps/capcut</li>
				<li>https://getmodsapk.com/3591-mechat-mod-apk/</li>
				<li>https://liteapks.com/spotify-2.html</li>
			</ol>
		</div>
	</div>


	<form id="manual-submit-form" class="ai-manual-form">
		<?php wp_nonce_field('manual_submit_ajax', 'manual_submit_nonce'); ?>
		
		<div class="ai-input-group floating-label">
			<div class="ai-input-wrapper">
				<input 
					type="url"
					name="url"
					id="manual-submit-url"
					placeholder=" "
					required
					autocomplete="off"
				>
				<label for="manual-submit-url"><?php _e('Single Post URL (App or Game)', TEXT_DOMAIN); ?></label>
				<span class="ai-input-icon">🔗</span>
			</div>
		</div>

		
		<div class="ai-submit-row">
		<button type="submit" class="button button-primary ai-submit-btn">
		<?php _e('🚀 Submit Manual', TEXT_DOMAIN); ?>
		</button>
		</div>
		
	</form>
	
	<div id="manual-submit-result" class="card-list"></div>
	
	</div>
	</div>
</div>

<script>
document.addEventListener('DOMContentLoaded', () => {

  // ======== ELEMENT REFERENCES ========
  const form = document.getElementById('manual-submit-form');
  const input = document.getElementById('manual-submit-url');
  const resultBox = document.getElementById('manual-submit-result');
  const noticeBox = document.getElementById('manual-notices');
  const detectedSourceEl = document.getElementById('manual-detected-source');
  const overlay = document.getElementById('manual-loading-overlay');
  const nonce = form.querySelector('#manual_submit_nonce')?.value || '';

  // ======== ALLOWED SOURCES ========
  const allowedSources = {
    '5play'     : '5play.org',
    'getmodsapk': 'getmodsapk.com',
    'apkmody'   : 'apkmody.com',
    'liteapks'  : 'liteapks.com',
    'playstore'  : 'play.google.com',
    'custom'    : null,
  };

  // ======== FUNCTION: Detect Source from URL ========
  function detectSource(url) {
    let host = '-';
    let source = 'custom';
    try { host = new URL(url).host; } catch(e) {}

    for (const [key, domain] of Object.entries(allowedSources)) {
      if (domain && host.includes(domain)) {
        source = key;
        break;
      }
    }

    // Update detected info in UI
    document.getElementById('manual-detected-host').textContent = host;
    detectedSourceEl.textContent = source;

    // Highlight badge if known source
    detectedSourceEl.classList.remove('highlight');
    if (source !== 'custom' && source !== '-') {
      detectedSourceEl.classList.add('highlight');
      setTimeout(() => detectedSourceEl.classList.remove('highlight'), 1200);
    }

    return { host, source };
  }

  // ======== INPUT HANDLING ========
  // Remove spaces automatically while typing
  input.addEventListener('input', e => {
    const value = e.target.value.replace(/\s+/g, '');
    e.target.value = value;
    detectSource(value);
  });

  // Handle paste event to remove spaces
  input.addEventListener('paste', e => {
    e.preventDefault();
    const pasted = (e.clipboardData || window.clipboardData).getData('text').replace(/\s+/g, '');
    input.value = pasted;
    detectSource(pasted);
  });

  // ======== FORM SUBMIT HANDLER ========
  form.addEventListener('submit', async e => {
    e.preventDefault();
    noticeBox.innerHTML = '';

    // Show overlay loading
    overlay.style.display = 'flex';

    const url = input.value.trim();
    if (!url) {
      noticeBox.innerHTML = '<span style="color:red;">Please enter a valid URL.</span>';
      overlay.style.display = 'none';
      return;
    }

    const { source } = detectSource(url);

    // ======== CHECK IF SOURCE IS ALLOWED ========
    if (source === 'custom') {
      // Not allowed, show warning and stop submit
      noticeBox.innerHTML = `
        <div style="padding:8px; border:1px solid #f5c2c7; background:#ffe2e6; color:#a71d2a; border-radius:6px;">
          ⚠ The source of this URL is not allowed.
        </div>`;
      overlay.style.display = 'none';
      return;
    } else if (['apkmody', 'getmodsapk', 'liteapks'].includes(source)) {
      // Warning if API Key may be required
      noticeBox.innerHTML = `
        <div style="padding:8px; border:1px solid #fff4e5; background:#fff4e5; color:#b45f00; border-radius:6px;">
          ⚠ For <strong>${source.toUpperCase()}</strong> sources, make sure you have entered a valid API Key or token.
          <br><br>
          <strong>Add Your Api Key Here → <a href="<?php echo admin_url(); ?>admin.php?page=_options&tab=20" target="_blank">API Key Settings</a></strong>
        </div>`;
    }

    const submitBtn = form.querySelector('.ai-submit-btn');
    submitBtn.classList.add('loading');
    submitBtn.disabled = true;

    // ======== AJAX MANUAL SUBMIT ========
    try {
      const data = new URLSearchParams();
      data.append('action', 'manual_submit_post');
      data.append('nonce', nonce);
      data.append('url', url);

      const response = await fetch(ajaxurl, { method: 'POST', body: data });
      const text = await response.text();
      let res;

      try {
        res = JSON.parse(text);
      } catch (err) {
        noticeBox.innerHTML += `<div style="color:red; margin-top:8px;">✗ Invalid JSON response</div>`;
        submitBtn.classList.remove('loading');
        submitBtn.disabled = false;
        overlay.style.display = 'none';
        return;
      }

      // Hide overlay after fetch
      overlay.style.display = 'none';
      submitBtn.classList.remove('loading');
      submitBtn.disabled = false;

      if (res.success) {
        const r = res.data;
        const m = r.meta || {};
        const s = r.scraper_data || {};

        // ======== EXTRACT DATA ========
        const title     = m.wp_title_GP || s.title_GP || 'Unknown Title';
        const poster    = m.wp_poster_GP || s.poster_GP || 'https://via.placeholder.com/180x180?text=No+Image';
        const version   = m.wp_version_GP || s.version_GP || '-';
        const updated   = m.wp_updates_GP || s.apk_updates || '-';
        const genre     = m.wp_categories_GP || s.genres_GP || '-';
        const developer = s.developer || s.developers_GP || '-';
        const shortDesc = (m.wp_desck_GP || s.new_desck_GP || s.description || '').substring(0,180)+'...';
        const editLink  = r.edit_link ? `<a href="${r.edit_link}" target="_blank" class="edit-post-link">Edit Post</a>` : '';

        // ======== RENDER CARD ========
        const cardHtml = `
<div class="card-item">
  <div class="card-close">×</div>
  <div class="card-left">
    <img class="card-poster" src="${poster}" alt="${title}">
    <div class="card-buttons small-screen-only">${editLink}</div>
  </div>
  <div class="card-content">
    <div class="title-with-edit">
      <h3>${title} v.${version}</h3>
      <div class="large-screen-only edit-in-title">${editLink}</div>
    </div>
    <div class="card-meta">
      <span>Devs: ${developer}</span>
      <span>Genre: ${genre}</span>
      <span>Source: ${r.detected_source || '-'}</span>
    </div>
    <div class="card-description">Updated: ${updated} – ${shortDesc}</div>
  </div>
</div>`;

        // Add card on top
        resultBox.insertAdjacentHTML('afterbegin', cardHtml);

        // Reset form and detected info
        form.reset();
        detectSource('');

      } else {
        const r = res.data ?? {};
        noticeBox.innerHTML += `<div style="color:red; margin-top:8px;">✗ ${r.message || 'Unknown error'}</div>`;
      }

    } catch (err) {
      // Hide overlay and remove button loading on error
      overlay.style.display = 'none';
      submitBtn.classList.remove('loading');
      submitBtn.disabled = false;
      noticeBox.innerHTML += `<div style="color:red; margin-top:8px;">✗ Connection error: ${err.message}</div>`;
    }

  });

  // ======== CLOSE CARD ANIMATION ========
  resultBox.addEventListener('click', e => {
    if (e.target.classList.contains('card-close')) {
      const card = e.target.closest('.card-item');
      card.classList.add('closing');
      setTimeout(() => card.remove(), 400);
    }
  });

});

</script>

<script>
document.addEventListener('DOMContentLoaded', () => {
    const toggle = document.querySelector('.example-collapse-toggle');
    const box = document.querySelector('.example-collapse-box');

    toggle.addEventListener('click', () => {
        box.classList.toggle('active');
    });
});
</script>

<style>
.example-collapse-box{border:1px solid #e5e7eb;border-radius:12px;background:#ffffff;max-width:900px;margin-bottom:20px}
.example-collapse-toggle{width:100%;background:none;border:none;padding:14px 18px;font-size:16px;font-weight:600;color:#111827;display:flex;justify-content:space-between;align-items:center;cursor:pointer}
.example-collapse-toggle:hover{background:#f9fafb}
.example-collapse-toggle .panah{transition:transform 0.3s ease;font-size:18px}
.example-collapse-content{max-height:0;overflow:hidden;transition:max-height 0.35s ease;padding:0 18px}
.example-collapse-content .app-description{margin:10px 0 12px;color:#374151;font-size:14px}
.example-collapse-box.active .example-collapse-content{max-height:600px;padding-bottom:18px}
.example-collapse-box.active .panah{transform:rotate(180deg)}
.example-collapse-content a{color:#2563eb;text-decoration:none;word-break:break-all}
.example-collapse-content a:hover{text-decoration:underline}.aps-tab-content.active{display:block}
.ai-manual-box{border-radius:10px}
.ai-center-title{text-align:center;font-size:18px;margin-bottom:15px}
.ai-notice-area > div{margin-bottom:10px}
.ai-detected-info{background:#f6f7f7;border-left:4px solid #2271b1;padding:10px 14px;font-size:13px;border-radius:6px;margin-bottom:15px}
.ai-separator{margin:0 6px;color:#999}
.ai-source-badge{padding:3px 8px;border-radius:4px;font-weight:500;transition:all 0.3s ease}
.ai-source-badge.highlight{background:#2271b1;animation:highlightPulse 1.2s ease-out}
@keyframes highlightPulse{0%{background:#2271b1;transform:scale(1.05)}
100%{background:transparent;transform:scale(1)}
}
.ai-manual-form{background:#fff;border:1px solid #e5e5e5;border-radius:10px;padding:20px 0;}
.ai-input-group label{display:block;font-weight:600;margin-bottom:6px}
.ai-input-wrapper{position:relative}
.ai-input-wrapper input{width:100%;padding:10px 44px 10px 14px;font-size:15px;border-radius:8px;border:1px solid #ccd0d4;transition:all 0.2s ease}
.ai-input-wrapper input:focus{border-color:#2271b1;box-shadow:0 0 0 2px rgba(34,113,177,0.15);outline:none}
.ai-input-icon{position:absolute;right:14px;top:50%;transform:translateY(-50%);font-size:18px;opacity:0.6;pointer-events:none}
.ai-help-text{display:block;margin-top:6px;font-size:12px;color:#666}
.ai-submit-row{display:flex;justify-content:center;margin-top:20px}
.ai-submit-btn{padding:10px 24px !important;border-radius:8px !important;font-weight:600;font-size:15px;min-width:200px;position:relative;overflow:hidden;transition:all 0.25s ease}
.ai-submit-btn.loading{pointer-events:none;color:transparent !important}
.ai-submit-btn.loading::after{content:'';position:absolute;top:50%;left:50%;width:22px;height:22px;border:3px solid #ffffff;border-top-color:transparent;border-radius:50%;transform:translate(-50%,-50%);animation:spinner 0.9s linear infinite}
@keyframes spinner{to{transform:translate(-50%,-50%) rotate(360deg)}
}
.card-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:24px;margin-top:24px}
.card-item{display:flex;border:1px solid #e1e1e1;border-radius:12px;overflow:hidden;background:#fff;box-shadow:0 4px 12px rgba(0,0,0,0.06);transition:all 0.25s ease;position:relative}
.card-item:hover{transform:translateY(-6px);box-shadow:0 12px 28px rgba(0,0,0,0.12)}
.card-item.closing{opacity:0;transform:scale(0.94);transition:all 0.4s ease}
.card-left{flex-shrink:0;display:flex;flex-direction:column}
.card-poster{width:90px;height:110px;padding:1rem 1rem 0 1rem;object-fit:cover}
.card-content{padding:16px 0;flex-grow:1;display:flex;flex-direction:column}
.title-with-edit{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:8px}
.title-with-edit h3{margin:0;font-size:1.28em;line-height:1.3;flex-grow:1}
.edit-post-link{padding:6px 14px;background:#1e73be;color:white;border-radius:6px;text-decoration:none;font-size:0.88em;white-space:nowrap;transition:background 0.2s}
.edit-post-link:hover{background:#165a99}
.card-meta{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px;font-size:0.86em}
.card-meta span{background:#f0f2f5;padding:4px 10px;border-radius:6px;color:#444}
.card-description{font-size:0.92em;color:#555;line-height:1.45;margin-bottom:12px}
.card-buttons{display:flex;gap:10px;flex-wrap:wrap;margin-top:auto}
.card-buttons a{padding:7px 14px;background:#1e73be;color:white;border-radius:6px;text-decoration:none;font-size:0.88em}
.card-close{position:absolute;top:1px;left:1px;width:28px;height:28px;background:black;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:20px;color:white;box-shadow:0 2px 8px rgba(0,0,0,0.15);transition:all 0.2s ease;z-index:10}
.card-close:hover{background:white;transform:scale(1.15)}
.import-loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(255,255,255,0.85);border-radius:12px;z-index:999}
.import-spinner{width:50px;height:50px;border:5px solid #e0e0e0;border-top:5px solid #2271b1;border-radius:50%;animation:spin 1s linear infinite;margin-bottom:15px}
@keyframes spin{0%{transform:rotate(0deg)}
100%{transform:rotate(360deg)}
}
.import-loading-overlay p{font-size:1.1em;color:#333;font-weight:500}
.small-screen-only{display:none}
.large-screen-only{display:flex}
@media (max-width:680px){.card-list{grid-template-columns:1fr;gap:16px}
.card-item{width:100% !important;flex-direction:row;height:auto}
.card-left{flex:0 0 90px}
.card-content{padding:16px 0}
.card-poster{width:90px;height:110px;padding:1rem 1rem 0 1rem}
.card-meta,.edit-in-title{display:none !important}
.small-screen-only{display:flex;margin-top:12px;justify-content:center}
.card-close{top:8px;left:8px;right:auto}
}
@media (min-width:681px){.card-item{max-width:100%}
}.aps-tab-content.active{display:block}

</style>
	

		<?php
		return ob_get_clean();
	}

	/**
	 * Render seluruh bagian daftar post impor (judul + tabel + pesan selesai)
	 * Persis sama dengan HTML yang diberikan, tanpa perubahan apapun pada struktur, class, teks, atau logika
	 *
	 * @param int    $count    Jumlah total item
	 * @param array  $items    Array data items
	 * @param object $sc       Instance class StructurCode
	 * @param array  $settings Array pengaturan
	 * @return string HTML lengkap untuk daftar impor
	 */
	public function renderImportPostList(int $count, array $items, object $sc, array $settings): string
	{
		ob_start();
		?>
		<h2 style="/* display:flex; justify-content:center; */font-size: 1.1rem;">
		  List <?php echo $count; ?> Post from &nbsp;<a href="<?php echo $settings['base_url']; ?>" target="_blank"><?php echo esc_html(parse_url($settings['base_url'])['host']); ?></a>
		</h2>
		<table id="ai-import-table" class="wp-list-table widefat fixed striped posts ai-import-table">
		  <thead>
			<tr>
				<td class="manage-column column-cb check-column"></td>
				<th class="manage-column column-thumb"><?php _e('Image', TEXT_DOMAIN); ?></th>
				<th class="manage-column column-title column-primary"><?php _e('Title', TEXT_DOMAIN); ?></th>
				<th class="manage-column column-mods"><?php _e('Mod', TEXT_DOMAIN); ?></th>
				<th class="manage-column column-appid"><?php _e('App ID', TEXT_DOMAIN); ?></th>
				<th class="manage-column column-source"><?php _e('Source', TEXT_DOMAIN); ?></th>
				<th class="manage-column column-status"><?php _e('Status', TEXT_DOMAIN); ?></th>
				<th class="manage-column column-action"><?php _e('Action', TEXT_DOMAIN); ?></th>
			</tr>
		</thead>

		  <tbody id="the-list">
		   
			<?php
			for ($i = 0; $i < $count; $i++) { 
				$item = $items[$i] ?? [];

				// Ambil App ID (bisa null)
				$appId = $sc->getAppIDs($item['title'] ?? '', $item['url'] ?? $item['link'] ?? '', $item);

				// Tentukan posterUrl dengan prioritas:
				// 1. Jika ada $appId → gunakan GetAppsPoster
				// 2. Jika tidak → gunakan $item['image']
				$posterUrl = '';
				if (!empty($appId) && is_string($appId)) {
					$posterFromGP = $sc->GetAppsPoster($appId);
					if (!empty($posterFromGP) && filter_var($posterFromGP, FILTER_VALIDATE_URL)) {
						$posterUrl = $posterFromGP;
					}
				}

				// Fallback ke gambar dari scraper jika GP gagal/tidak ada
				if (empty($posterUrl) && !empty($item['image'])) {
					$posterUrl = trim($item['image']);
				}

				// Fallback terakhir: placeholder
				if (empty($posterUrl)) {
					$posterUrl = 'https://via.placeholder.com/64?text=No+Image';
				}

				echo $sc->Render_List_Auto(
					item: $item,
					i: $i,
					sc: $sc,
					posterUrl: $posterUrl,
					appId: $appId ?? '',   // kirim string kosong jika null
					settings: $settings ?? []
				);
			}
			?>
		  </tbody>
		</table>
		
		<?php
		echo $sc->renderImportCompleteMessage('You can now review or publish all new posts.');
		//echo '<div style="margin: 20px 0;">';
		//echo $this->renderClearCacheButton();
		//echo '</div>';
		?>
		
		<?php
		return ob_get_clean();
	}

    public function render_post_status_info($opt_themes = []) 
	{

        if (empty($this->options['apk_status'])) {
            return '';
        }

        $status = htmlspecialchars($this->options['apk_status']);

        ob_start();
        ?>
        <ul class="play_menu">
            <li>
                Your Status Post is
                <?php if ($status !== 'draft'): ?>
                    <blink>
                        <strong class="blink blink-one" style="color:green">
                            <?= $status; ?>
                        </strong>
                    </blink>
                    You ready to Make auto posting now
                <?php else: ?>
                    <blink>
                        <strong class="blink blink-one" style="color:red">
                            <?= $status; ?>
                        </strong>
                    </blink>.
                    Please Change to
                    <blink>
                        <strong class="blink" style="color:green">publish</strong>
                    </blink>
                    to make Auto Posting, you can go to Setting Page
                <?php endif; ?>
            </li>
        </ul>
	<?php
	return ob_get_clean();
    }
	
	public function render_result_post(array $data, int $post_id, string $urlX, string $image_url)
	{
		// Validasi data wajib
		if (empty($data['title_GP']) || is_wp_error($data['title_GP'])) {
			return '';
		}

		// Normalisasi data
		$version   = !empty($data['version_gps']) ? 'v.' . $data['version_gps'] : 'v.' . ($data['version_sc'] ?? '');
		$genre     = $data['genres_GP']     ?? $data['genre_sc']      ?? '';
		$developer = $data['developers_GP'] ?? '';
		$desck     = $data['desck_GP']       ?? $data['summary_sc']    ?? '';
		$update    = $data['updates_GP']     ?? $data['updated_sc']    ?? '';
		$title     = $data['title_GP']       ?? $data['app_name']      ?? '';
		$category  = $data['p_category']     ?? '';

		ob_start();
		?>
		<link rel="stylesheet" href="<?php echo EX_THEMES_URI; ?>/libs/addons/assets/css/result.css">
		<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.1/css/all.min.css">

		<div class="-app-card-container">
			<div class="app-card">

				<div class="card-header">
					<a class="app-icon" href="<?php echo esc_url($urlX); ?>" target="_blank">
						<img src="<?php echo esc_url($image_url); ?>" width="70" height="70">
					</a>

					<div class="app-info">
						<div class="app-name">
							<a class="app-name-link"
							   href="post.php?post=<?php echo (int)$post_id; ?>&action=edit"
							   target="_blank">
								<?php echo esc_html($title); ?> - <b><?php echo esc_html($version); ?></b>
							</a>
						</div>

						<div class="app-details">
							<div class="app-stars">
								<span class="stars-score" style="width: <?php echo mt_rand(50, 90); ?>%"></span>
							</div>
							<span class="delimiter"></span>
							<span class="app-author"><?php echo esc_html($developer); ?></span>
						</div>

						<p class="app-desc">
							<?php echo esc_html(trim(strip_tags($desck))); ?>
							<b> — Updates on <?php echo esc_html(trim(strip_tags($update))); ?></b>
						</p>

						<p class="app-tags">
							<?php if ($category): ?>
								<span class="dt-app-tag"><?php echo esc_html($category); ?></span>
							<?php endif; ?>
							<?php if ($genre): ?>
								<span class="dt-app-tag"><?php echo esc_html($genre); ?></span>
							<?php endif; ?>
						</p>
					</div>
				</div>

			</div>
		</div>

		<div class="alert alert-success">
			<button type="button" class="close" data-dismiss="alert">×</button>
			<div class="icon hidden-xs">
				<img src="<?php echo esc_url($image_url); ?>" width="75" height="75">
			</div>
			<h3><?php echo esc_html($title); ?></h3>
			<a href="<?php echo esc_url($urlX); ?>" target="_blank">View</a> -
			<a href="post.php?post=<?php echo (int)$post_id; ?>&action=edit" target="_blank">Edit</a>
		</div>
	
	<?php
	return ob_get_clean();
	}

    public function render_debug_app( $data = [], $url = '' ) 
	{
        if ( empty($this->options['debug_on']) ) {
            return;
        }

        if ( empty($data['title_GP']) || is_wp_error($data['title_GP']) ) {
            echo defined('NO_ID') ? NO_ID : '';
            return;
        }

        // ===== URL PARSE =====
        $urlX   = $url;
        $parse = parse_url($urlX);
        $urlX1 = isset($parse['host'])
            ? preg_replace(
                "/^([a-zA-Z0-9].*\.)?([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z.]{2,})$/",
                '$2',
                $parse['host']
            )
            : '';

        $language = $this->options['apk_language'] ?? '';
        $arr['languages'] = $language;

        ?>
        <!-- ================= DEBUG TERMINAL ================= -->
        <div id="terminal-debug">
            <div class="terminal-body">

                <?php if (!empty($data['GP_ID'])): ?>
                <section class="terminal-section">
                    <div class="terminal-prompt">
                        $ fetch
                        <a href="https://play.google.com/store/apps/details?id=<?php echo esc_attr($data['GP_ID']); ?>"
                           target="_blank" style="color:#7ee787">playstore</a>
                    </div>

                    <div class="terminal-grid">
                        <?php
                        $map = [
                            'PACKAGE'   => 'GP_ID',
                            'APP'       => 'title_GP',
                            'VERSION'   => 'version_GP',
                            'SIZE'      => 'sizes_GP',
                            'CATEGORY'  => 'genres_GP',
                            'DEVELOPER' => 'developers_GP',
                            'INSTALLS'  => 'installs_GP',
                            'UPDATED'   => 'updates_GP',
                            'REQUIRES'  => 'requires_GP',
                            'RATED'     => 'rated_GP',
                            'VOTES'     => 'ratings_GP',
                            'YOUTUBE'   => 'youtube_GP',
                            'PAID'      => 'paid_GP1',
                            'PAID#2'    => 'paid_GP2',
                        ];

                        foreach ($map as $label => $key):
                            if (!empty($data[$key])):
                        ?>
                            <div>
                                <label><?php echo esc_html($label); ?></label>
                                <span><?php echo esc_html($data[$key]); ?></span>
                            </div>
                        <?php endif; endforeach; ?>
                    </div>
                </section>
                <?php endif; ?>

                <?php
                $blocks = [
                    'summary.txt'   => 'desck_GP',
                    'whats-new.log' => 'whatnews_GP',
                    'article.md'    => 'articlebody_GP',
                ];

                foreach ($blocks as $file => $key):
                    if (!empty($data[$key])):
                ?>
                <section class="terminal-section">
                    <div class="terminal-prompt">$ cat <?php echo esc_html($file); ?></div>
                    <pre class="terminal-pre"><?php echo esc_html(trim(strip_tags($data[$key]))); ?></pre>
                </section>
                <?php endif; endforeach; ?>

                <section class="terminal-section">
                    <div class="terminal-prompt">
                        $ fetch
                        <a href="<?php echo esc_url($url); ?>" target="_blank" style="color:#7ee787">
                            <?php echo esc_html($urlX1); ?>
                        </a>
                    </div>

                    <div class="terminal-grid">
                        <?php
                        $fields = [
                            'Title'     => $data['title'] ?? '',
                            'App Name'  => $data['app_name'] ?? '',
                            'Version'   => $data['version_sc'] ?? '',
                            'Genre'     => $data['genre_sc'] ?? '',
                            'Size'      => $data['size_sc'] ?? '',
                            'Developer' => $data['developer_sc'] ?? '',
                            'Updated'   => $data['updated_sc'] ?? '',
                        ];

                        foreach ($fields as $label => $value):
                            if (empty($value)) continue;
                        ?>
                            <div>
                                <label><?php echo esc_html($label); ?></label>
                                <span><?php echo esc_html($value); ?></span>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </section>

                <?php
                $blocks2 = [
                    'short-mods.txt'        => 'mods',
                    'full-mod.txt'          => 'full_mod',
                    'article-content.md'    => 'article_content',
                ];

                foreach ($blocks2 as $file => $key):
                    if (!empty($data[$key])):
                ?>
                <section class="terminal-section">
                    <div class="terminal-prompt">$ cat <?php echo esc_html($file); ?></div>
                    <pre class="terminal-pre"><?php echo esc_html(trim(strip_tags($data[$key]))); ?></pre>
                </section>
                <?php endif; endforeach; ?>

                <?php
                // ===== DOWNLOAD LINKS GMA =====
                if (!empty($data['downloadlinks_gma']) && is_array($data['downloadlinks_gma'])) {

                    $output = [];
                    $count  = count($data['downloadlinks_gma']);

                    for ($i = 0; $i < $count; $i++) {

                        if (empty($data['name_downloadlinks_gma'][$i])) continue;

                        $block  = "DOWNLOAD #" . ($i + 1) . "\n";
                        $block .= "NAME  : " . $data['name_downloadlinks_gma'][$i] . "\n";
                        $block .= "LINK  : " . ($data['downloadlink_gma'][$i] ?? $data['downloadlinks_gma'][$i] ?? '-') . "\n";

                        if (!empty($data['apklink'][$i])) {
                            $block .= "APK   : " . $data['apklink'][$i] . "\n";
                        }

                        if (!empty($data['size_downloadlinks_gma'][$i])) {
                            $block .= "SIZE  : " . wp_strip_all_tags($data['size_downloadlinks_gma'][$i]) . "\n";
                        }

                        if (!empty($data['type_downloadlink_gma'][$i])) {
                            $block .= "TYPE  : " . $data['type_downloadlink_gma'][$i] . "\n";
                        }

                        if (!empty($data['notes_downloadlinks_gma'][$i])) {
                            $block .= "NOTE  : " . $data['notes_downloadlinks_gma'][$i] . "\n";
                        }

                        $block .= str_repeat('-', 40);
                        $output[] = $block;
                    }

                    if (!empty($output)) :
                ?>
                <section class="terminal-section">
                    <div class="terminal-prompt">$ cat download_links.txt</div>
                    <pre class="terminal-pre"><?php echo esc_html(implode("\n", $output)); ?></pre>
                </section>
                <?php endif; } ?>

                <div class="terminal-footer">
                    root@parser:~$ <span class="blink">_</span>
                </div>

            </div>
        </div>

		<style>
		#terminal-debug {background: #0d1117;color: #c9d1d9;font-family: JetBrains Mono, monospace;border-radius: 10px;margin: 20px 0;box-shadow: 0 20px 50px rgba(0,0,0,.6);overflow: visible;}.terminal-header {background: #161b22;padding: 10px;display: flex;align-items: center;}.dot {width: 12px;height: 12px;border-radius: 50%;margin-right: 6px;}.red {background: #ff5f56;}.yellow {background: #ffbd2e;}.green {background: #27c93f;}.terminal-title {margin-left: 12px;font-size: 12px;color: #8b949e;}.terminal-body {padding: 15px;max-height: none;overflow: visible;}.terminal-section {margin-bottom: 25px;}.terminal-prompt {color: #7ee787;margin-bottom: 8px;}.terminal-grid {display: grid;grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));gap: 8px;}.terminal-grid div {background: #010409;border: 1px solid #21262d;padding: 6px 10px;border-radius: 6px;}.terminal-grid label {font-size: 10px;color: #8b949e;display: block;}.terminal-pre {background: #010409;border: 1px solid #21262d;border-radius: 6px;padding: 12px;white-space: pre-wrap;line-height: 1.6;color: #fff;}.terminal-list {list-style: none;padding: 0;margin: 0;}.terminal-list li {padding: 6px 0;border-bottom: 1px dashed #21262d;}.terminal-footer {padding-top: 10px;color: #7ee787;}.blink {animation: blink 1s infinite;}@keyframes blink {50% {opacity: 0;}}
		</style>

	<?php
    }

    public function render_manual_post_form($demos = '') 
	{

        if (empty($demos)) {
            return '';
        }

        $host  = parse_url($demos, PHP_URL_HOST);
        $host  = htmlspecialchars($host);
        $demos = htmlspecialchars($demos);

        ob_start();
        ?>

        <div class="play_menu" style="text-transform:uppercase">
            <i class="fa fa-pencil-square-o" aria-hidden="true"></i>&nbsp;
            <b>Paste your link post here</b>
        </div>

        <div class="play_menu">
            <form name="myForm" id="myForm" method="POST" class="f">
                <input type="text" name="wp_url" placeholder="example : <?= $demos; ?>">
                <input type="submit" id="Submit" name="wp_sb" value="<?php echo postnow; ?>">
            </form>
        </div>

        <div class="play_menu" style="text-transform:uppercase">
            <b>Add manual</b>
        </div>

        <div class="play_menu" style="text-transform:uppercase">
            <ol style="paddiing-right:20px !important; margin:20px;">
                <li>
                    Open website
                    <a style="color:var(--color_link_h)!important;font-weight:700;"
                       href="https://<?= $host; ?>"
                       target="_blank" rel="noopener">
                        <?= $host; ?>
                    </a>
                </li>
                <li>Copy link post and paste to form</li>
                <li>
                    use the url into this format:
                    <strong style="color:var(--color_link_h)!important;font-weight:700;text-transform:lowercase!important">
                        <?= $demos; ?>
                    </strong>
                </li>
            </ol>
        </div>

	<?php
	return ob_get_clean();
    }

	public function games_page_navi($paged, $total_pages, $sc_page = 'sc-5play') 
	{

		if ($total_pages <= 1) {
			return '';
		}

		$paged       = max(1, (int)$paged);
		$total_pages = max(1, (int)$total_pages);

		ob_start();
		?>
		<div class="nav_wrapper">
			<!-- Pagination -->
			<nav aria-label="Page navigation">
				<ul class="pagination">

					<!-- First -->
					<li class="page-item hide-mobile <?= $paged <= 1 ? 'disabled' : '' ?>">
						<a class="page-link" href="?page=<?= $sc_page ?>&games=1">
							<span class="desktop-only">First</span>
							<span class="mobile-only">««</span>
						</a>
					</li>

					<!-- Previous -->
					<li class="page-item <?= $paged <= 1 ? 'disabled' : '' ?>">
						<a class="page-link" href="?page=<?= $sc_page ?>&games=<?= $paged - 1 ?>">
							<span class="desktop-only">Prev</span>
							<span class="mobile-only">«</span>
						</a>
					</li>

					<?php
					$visible = 5;
					$start = max(1, $paged - floor($visible / 2));
					$end   = min($total_pages, $start + $visible - 1);

					if ($end - $start + 1 < $visible) {
						$start = max(1, $end - $visible + 1);
					}
					?>

					<!-- Ellipsis kiri -->
					<?php if ($start > 1): ?>
						<li class="page-item">
							<a class="page-link" href="?page=<?= $sc_page ?>&games=1">1</a>
						</li>
						<?php if ($start > 2): ?>
							<li class="page-item"><span class="page-link ellipsis">...</span></li>
						<?php endif; ?>
					<?php endif; ?>

					<!-- Nomor halaman -->
					<?php for ($i = $start; $i <= $end; $i++): ?>
						<li class="page-item <?= $i == $paged ? 'active' : '' ?>">
							<a class="page-link" href="?page=<?= $sc_page ?>&games=<?= $i ?>">
								<?= $i ?>
							</a>
						</li>
					<?php endfor; ?>

					<!-- Ellipsis kanan -->
					<?php if ($end < $total_pages): ?>
						<?php if ($end < $total_pages - 1): ?>
							<li class="page-item"><span class="page-link ellipsis">...</span></li>
						<?php endif; ?>
						<li class="page-item">
							<a class="page-link" href="?page=<?= $sc_page ?>&games=<?= $total_pages ?>">
								<?= $total_pages ?>
							</a>
						</li>
					<?php endif; ?>

					<!-- Next -->
					<li class="page-item <?= $paged >= $total_pages ? 'disabled' : '' ?>">
						<a class="page-link" href="?page=<?= $sc_page ?>&games=<?= $paged + 1 ?>">
							<span class="desktop-only">Next</span>
							<span class="mobile-only">»</span>
						</a>
					</li>

					<!-- Last -->
					<li class="page-item hide-mobile <?= $paged >= $total_pages ? 'disabled' : '' ?>">
						<a class="page-link" href="?page=<?= $sc_page ?>&games=<?= $total_pages ?>">
							<span class="desktop-only">Last</span>
							<span class="mobile-only">»»</span>
						</a>
					</li>

				</ul>
			</nav>

			<!-- Go to Page -->
			<div class="go-to">
				<span>Go to page:</span>
				<input type="number"
					   id="goto-page-input"
					   min="1"
					   max="<?= $total_pages ?>"
					   value="<?= $paged ?>">
				<button id="goto-page-btn">Go</button>
			</div>
		</div>

		<script>
		document.addEventListener('DOMContentLoaded', function() {
			const btn = document.getElementById('goto-page-btn');
			const input = document.getElementById('goto-page-input');
			const maxPage = <?= $total_pages ?>;

			function goToPage() {
				let page = parseInt(input.value, 10);
				if (isNaN(page) || page < 1) page = 1;
				if (page > maxPage) page = maxPage;

				window.location.href = '?page=<?= $sc_page ?>&games=' + page;
			}

			btn.addEventListener('click', goToPage);

			input.addEventListener('keypress', function(e) {
				if (e.key === 'Enter') {
					e.preventDefault();
					goToPage();
				}
			});
		});
		</script>
	<?php
	return ob_get_clean();
	}

	public function apps_page_navi($paged, $total_pages, $sc_page = 'sc-5play') 
	{

		if ($total_pages <= 1) {
			return '';
		}

		$paged       = max(1, (int)$paged);
		$total_pages = max(1, (int)$total_pages);

		ob_start();
		?>
		<div class="nav_wrapper">
			<!-- Pagination -->
			<nav aria-label="Page navigation">
				<ul class="pagination">

					<!-- First -->
					<li class="page-item hide-mobile <?= $paged <= 1 ? 'disabled' : '' ?>">
						<a class="page-link" href="?page=<?= $sc_page ?>&apps=1">
							<span class="desktop-only">First</span>
							<span class="mobile-only">««</span>
						</a>
					</li>

					<!-- Previous -->
					<li class="page-item <?= $paged <= 1 ? 'disabled' : '' ?>">
						<a class="page-link" href="?page=<?= $sc_page ?>&apps=<?= $paged - 1 ?>">
							<span class="desktop-only">Prev</span>
							<span class="mobile-only">«</span>
						</a>
					</li>

					<?php
					$visible = 5;
					$start = max(1, $paged - floor($visible / 2));
					$end   = min($total_pages, $start + $visible - 1);

					if ($end - $start + 1 < $visible) {
						$start = max(1, $end - $visible + 1);
					}
					?>

					<!-- Ellipsis kiri -->
					<?php if ($start > 1): ?>
						<li class="page-item">
							<a class="page-link" href="?page=<?= $sc_page ?>&apps=1">1</a>
						</li>
						<?php if ($start > 2): ?>
							<li class="page-item"><span class="page-link ellipsis">...</span></li>
						<?php endif; ?>
					<?php endif; ?>

					<!-- Nomor halaman -->
					<?php for ($i = $start; $i <= $end; $i++): ?>
						<li class="page-item <?= $i == $paged ? 'active' : '' ?>">
							<a class="page-link" href="?page=<?= $sc_page ?>&apps=<?= $i ?>">
								<?= $i ?>
							</a>
						</li>
					<?php endfor; ?>

					<!-- Ellipsis kanan -->
					<?php if ($end < $total_pages): ?>
						<?php if ($end < $total_pages - 1): ?>
							<li class="page-item"><span class="page-link ellipsis">...</span></li>
						<?php endif; ?>
						<li class="page-item">
							<a class="page-link" href="?page=<?= $sc_page ?>&apps=<?= $total_pages ?>">
								<?= $total_pages ?>
							</a>
						</li>
					<?php endif; ?>

					<!-- Next -->
					<li class="page-item <?= $paged >= $total_pages ? 'disabled' : '' ?>">
						<a class="page-link" href="?page=<?= $sc_page ?>&apps=<?= $paged + 1 ?>">
							<span class="desktop-only">Next</span>
							<span class="mobile-only">»</span>
						</a>
					</li>

					<!-- Last -->
					<li class="page-item hide-mobile <?= $paged >= $total_pages ? 'disabled' : '' ?>">
						<a class="page-link" href="?page=<?= $sc_page ?>&apps=<?= $total_pages ?>">
							<span class="desktop-only">Last</span>
							<span class="mobile-only">»»</span>
						</a>
					</li>

				</ul>
			</nav>
		</div>
	<?php
	return ob_get_clean();
	}

	public function render_app_item($args = []) 
	{		
		// Default values
		$defaults = [
			'counter'         => 1,
			'title'           => '',
			'versi'           => '',
			'link'            => '#',
			'url'             => '',          // alternatif untuk 'link' (lebih umum)
			'img'             => '',
			'image'           => '',
			'appId'           => '',
			'size'            => '',
			'mods'            => '',
			'getAppsCategory' => '',
		];

		$data = array_merge($defaults, $args);

		// Gunakan 'url' atau 'link' (lebih fleksibel)
		$detail_url = !empty($data['url']) ? $data['url'] : $data['link'];

		// =============================================
		// 1. Ambil title & MOD dari halaman detail (dengan cache)
		// =============================================
		$display_title = !empty($data['title']) ? trim($data['title']) : 'Unknown App';
		$mods_display  = !empty($data['mods'])  ? trim($data['mods'])  : '-';

		if (!empty($detail_url) && filter_var($detail_url, FILTER_VALIDATE_URL)) {
			$cache_key = 'detail_mod_item_' . md5($detail_url);

			$cached = get_transient($cache_key);
			if ($cached !== false && is_array($cached)) {
				$detail_title = $cached['title'] ?? '';
				$extracted_mod = $cached['mods'] ?? '-';
			} else {
				$detail_html = $this->fast_get_content($detail_url);

				$detail_title = '';
				$extracted_mod = '-';

				if (!empty($detail_html) && is_string($detail_html)) {
					if (preg_match('/<title[^>]*>(.*?)<\/title>/is', $detail_html, $m)) {
						$detail_title_raw = trim(html_entity_decode(strip_tags($m[1]), ENT_QUOTES | ENT_HTML5));

						if (!empty($detail_title_raw)) {
							$detail_title = $detail_title_raw;

							// Gunakan title dari detail jika lebih informatif
							if (strlen($detail_title) > strlen($display_title) + 15) {
								$display_title = $detail_title;
							}

							// Ekstrak MOD
							$extracted_mod = $this->get_mod_by_title_source(
								$detail_title,
								$this->settings['source'] ?? '5play' // asumsi $this->settings ada
							);

							// Simpan ke cache (12 jam)
							set_transient($cache_key, [
								'title' => $detail_title,
								'mods'  => $extracted_mod
							], 12 * HOUR_IN_SECONDS);
						}
					}
				}
			}

			// Update mods jika hasil ekstrak lebih baik
			if ($extracted_mod !== '-' && strlen($extracted_mod) > 3) {
				$mods_display = $extracted_mod;
			}
		}

		// Fallback akhir untuk mods
		if ($mods_display === '-' && !empty($data['mods'])) {
			$mods_display = trim($data['mods']);
		}

		// =============================================
		// 2. Sanitasi & persiapan output
		// =============================================
		$title       = esc_html($display_title);
		$version     = !empty($data['versi']) ? esc_html('v' . trim($data['versi'])) : '';
		$size        = !empty($data['size'])  ? esc_html(trim($data['size'])) : '';
		$mods        = !empty($mods_display)  ? esc_html($mods_display) : '';
		$link        = esc_url($detail_url ?: $data['link']);
		$appId       = esc_attr($data['appId'] ?? '');

		// Prioritas gambar: Google Play > image > img > placeholder
		$poster_gp = !empty($appId) ? $this->GetAppsPoster($appId) : '';
		$image_src = $poster_gp ?: ($data['image'] ?: ($data['img'] ?: ''));
		$final_img = $this->url_exists($image_src) ? esc_url($image_src) : 'https://via.placeholder.com/96?text=No+Image';

		// Gabungkan info kecil dengan pemisah yang rapi
		$meta_parts = array_filter([$mods, $size, $version]);
		$meta_text  = !empty($meta_parts) ? implode(' • ', $meta_parts) : '—';

		ob_start();
		?>		 
		<div class="col-12 col-md-6 mb-4">
			<span class="position-relative archive-post--remove app-container d-flex align-items-center">

				<div class="flex-shrink-0" style="position:relative;">
					<img src="<?= $final_img ?>"
						 class="app-logo"
						 width="64"
						 height="64"
						 loading="lazy">

					<!--<span style="position:absolute;
								 top:50%;
								 left:50%;
								 transform:translate(-50%,-50%);
								 background:rgba(0,0,0,0.85);
								 color:white;
								 padding:5px 9px;
								 border-radius:6px;
								 font-weight:bold;
								 font-size:13px;
								 border:2px solid white;">
						<?= (int)$data['counter'] ?>
					</span>-->
				</div>

				<div class="app-info ms-3 flex-grow-1">
					<h3 class="h5 font-weight-semibold app-title mb-1">
						<?= $data['title'] ?> <?= $version ?>  
					</h3>

					<div class="text-muted small">
						<?= $meta_text !== '—' ? $meta_text : '' ?>
					</div>
				</div>

				<div class="app-get">
					<form method="POST" target="_blank">
						<input type="hidden" name="wp_url" value="<?= $link ?>">
						<button type="submit"
								name="wp_sb"
								class="get-button btn btn-success btn-sm">
							<?= postnow ?>
						</button>
					</form>
				</div>

			</span>
		</div>
	
	<?php
	return ob_get_clean();
	}
	
	 /**
	 * Render satu baris <tr> untuk tabel daftar item Auto Posting
	 *
	 * @param array  $item       Data satu item dari array $items
	 * @param int    $i          Index (0-based, untuk penomoran #1, #2, dst)
	 * @param object $sc         Instance class StructurCode (untuk memanggil url_exists)
	 * @param string $posterUrl  URL poster dari Google Play (hasil GetAppsPoster)
	 * @param string $appId      Package name / App ID
	 * @param array  $settings   Array settings (minimal punya 'source' & 'base_url')
	 *
	 * @return string HTML satu baris <tr>
	 */
	public function Render_List_Auto(
		array $item,
		int $i,
		object $sc,
		string $posterUrl = '',
		?string $appId = null, 
		array $settings = [] 
	): string 
	{
		ob_start();
		
		// Static cache URL yang sudah diimport
		static $imported_urls = null;
		if ($imported_urls === null) {
			$imported_urls = $this->get_all_imported_urls(); // ambil dari postmeta
			// normalisasi URL
			$imported_urls = array_map(function($u){ return strtolower(rtrim($u,'/')); }, $imported_urls);
		}

		$item_url = !empty($item['url']) ? strtolower(rtrim($item['url'],'/')) : '';

		// ❌ Skip jika URL sudah diimport
		if ($item_url && in_array($item_url, $imported_urls, true)) {
			return ''; // jangan render baris ini
		}

		// Tentukan gambar akhir
		$default_placeholder = 'https://via.placeholder.com/64?text=No+Image';
		$final_image = '';
		if (!empty($item['image']) && $sc->url_exists($item['image'])) {
			$final_image = $item['image'];
		} elseif (!empty($posterUrl)) {
			$final_image = $posterUrl;
		} else {
			$final_image = $default_placeholder;
		}

		// Mods (prioritas dari parameter, lalu item['mods'], lalu fallback)
		
		// =============================================
		// 2. Ambil title & MOD dari halaman detail (dengan cache)
		// =============================================
		$display_title = !empty($item['title']) ? trim($item['title']) : 'Unknown Title';
		$mods_display   = !empty($item['mods']) ? esc_html(trim($item['mods'])) : '-';

		if (!empty($item['url']) && filter_var($item['url'], FILTER_VALIDATE_URL)) {
			$cache_key = 'detail_mod_' . md5($item['url']); // unik per URL

			// Coba ambil dari cache dulu (12 jam)
			$cached_data = get_transient($cache_key);
			if ($cached_data !== false && is_array($cached_data)) {
				$detail_title = $cached_data['title'] ?? '';
				$mods_display = $cached_data['mods'] ?? '-';
			} else {
				// Fetch konten halaman detail
				$detail_html = $sc->Go_Curl->fast_get_contents($item['url']);

				if (!empty($detail_html) && is_string($detail_html)) {
					// Ekstrak <title>
					if (preg_match('/<title[^>]*>(.*?)<\/title>/is', $detail_html, $matches)) {
						$detail_title_raw = trim(html_entity_decode(strip_tags($matches[1]), ENT_QUOTES | ENT_HTML5));

						if (!empty($detail_title_raw)) {
							$detail_title = $detail_title_raw;

							// Gunakan title detail jika lebih lengkap / informatif
							if (strlen($detail_title) > strlen($display_title) + 10) {
								$display_title = $detail_title;
							}

							// Ekstrak MOD
							$extracted_mod = $sc->get_mod_by_title_source(
								$detail_title,
								$settings['source'] ?? '5play'
							);

							if ($extracted_mod !== '-' && strlen($extracted_mod) > 3) {
								$mods_display = esc_html($extracted_mod);
							}

							// Simpan ke cache
							set_transient($cache_key, [
								'title' => $detail_title,
								'mods'  => $mods_display
							], 12 * HOUR_IN_SECONDS);
						}
					}
				}
			}
		}

		// Fallback terakhir: jika MOD masih '-', pakai dari $item jika ada
		if ($mods_display === '-' && !empty($item['mods'])) {
			$mods_display = esc_html(trim($item['mods']));
		}


		// Tentukan slug halaman admin berdasarkan source
		/* $page_slug = '';
		if (!empty($settings['source'])) {
			switch ($settings['source']) {
				case '5play':     $page_slug = '5play'; break;
				case 'getmodsapk': $page_slug = 'getmodsapk'; break;
				case 'apkmody':   $page_slug = 'apkmody'; break;
				case 'liteapks':  $page_slug = 'liteapks'; break;
			}
		}

		$admin_url = $page_slug 
			? admin_url('admin.php?page=sc-' . $page_slug) 
			: '#'; */

		$source_host = !empty($settings['base_url'])
			? esc_html(parse_url($settings['base_url'], PHP_URL_HOST))
			: 'Unknown';
		?>
 
		<tr class="ai-item" data-url="<?= esc_url($item['url'] ?? '#') ?>" data-index="<?= $i ?>">
			<th class="check-column"></th>

			<!-- IMAGE -->
			<td class="thumb column-thumb">
				<div class="ai-thumb-wrap">
					<img src="<?= esc_url($final_image) ?>" 
						 class="app-logo" 
						 width="64" 
						 height="64" 
						 loading="lazy" 
						 alt="<?= esc_attr($item['title'] ?? 'App') ?>">
				</div>
			</td>

			<!-- TITLE + VERSION -->
			<td class="title column-title column-primary">
				<strong class="ai-item-title">
					<?= esc_html($item['title'] ?? 'Unknown Title') ?> 
					<?= esc_html($item['versi'] ?? $item['version'] ?? '') ?>
				</strong>
				<div class="row-actions ai-row-meta">
					<span class="ai-index">#<?= $i + 1 ?></span>
					<span class="sep">•</span>
					<span class="status-text">Wait</span>
				</div>
			</td>

			<!-- MODS -->
			<td class="mods column-mods">
				<span class="ai-mods"><?= $mods_display ?></span>
			</td>

			<!-- APP ID -->
			<td class="appId column-appid">
				<span class="ai-appid">
					<?php if (!empty($appId)): ?>
						<a href="https://play.google.com/store/apps/details?id=<?= esc_attr($appId) ?>" target="_blank">
							<?= esc_html($appId) ?>
						</a>
					<?php else: ?>
						-
					<?php endif; ?>
				</span>
			</td>

			<!-- SOURCE -->
			<td class="source column-source">
				<span class="ai-source">
					<a href="<?= esc_url($item['url'] ?? '#') ?>" target="_blank">
						<?= $source_host ?>
					</a>
				</span>
			</td>

			<!-- STATUS -->
			<td class="status column-status">
				<span class="status-badge badge-waiting">Wait</span>
			</td>

			<!-- SUBMIT MANUAL -->
			<td class="appId column-appid">
			<!-- SUBMIT MANUAL -->
<td class="appId column-appid">
    <form id="post_manual" class="ai-auto-submit-form"
          data-url="<?= esc_url($item['url'] ?? '') ?>"
          data-index="<?= $i ?>">
        
        <?php wp_nonce_field('manual_submit_ajax', 'nonce'); ?>

        <button type="button"
                class="button button-primary ai-manual-submit-btn">
            🚀 Submit
        </button>
    </form>
</td>
				 
			</td>
		</tr>
	<?php
		return ob_get_clean();
	}

    public function Code_5play($url, $Go_Curl, $paged = 1) 
	{	
		// 1. Fetch konten dengan strategi bertahap 
		$options = [
			'timeout'         => 6,
			'connect_timeout' => 4,
			'follow_redirect' => true,
			'headers'         => [
				'User-Agent'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
				'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
				'Accept-Language' => 'en-US,en;q=0.5',
				'Referer'         => 'https://www.google.com/',
			]
		];
 
		$html = $this->fast_get_content($url, $options);
		
		// Retry 1: variasi UA + sedikit lebih panjang timeout
		if (empty($html) || strlen($html) < 2800) {
			$retry_options = $base_options;
			$retry_options['timeout'] = 8;
			$retry_options['headers']['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130 Safari/537.36';
			$html = $this->fast_get_content($url, $retry_options);
		}

		// Retry terakhir: bypass (paling lambat → hanya kalau benar-benar perlu)
		if (empty($html) || strlen($html) < 2800) {
			$html = $this->scrapedo($url);
		}

		// Jika tetap gagal setelah 3 percobaan
		if (empty($html) || strlen($html) < 2500) {
			return $this->error('Failed to fetch page from 5play.org after multiple attempts (likely Cloudflare protection is very strict at the moment).');
		}

        // ---------- MAIN BLOCK ----------
        preg_match('#<div class="glist app-list">(.*?)<div class="navigation fc">#s', $html, $m);
        $block = $m[1] ?? '';

        if (!$block) {
            return $this->error(
                'No post found – layout may have changed.'
            );
        }

        // ---------- DATA ----------
        preg_match_all('#<span class="title">(.*?)</span>#is', $block, $judul);
        preg_match_all('#<a[^>]+href="([^"]+)"#is', $block, $link);
        preg_match_all('#<img[^>]+src="([^"]+)"#is', $block, $img);
        preg_match_all('#<span class="meta meta-vers">.*?<i class="meta-item">(.*?)<\/i>#is', $block, $versi);

        $judul = $judul[1] ?? [];
        $link  = $link[1]  ?? [];
        $img   = $img[1]   ?? [];
        $versi = $versi[1] ?? [];
		
        // 4. Pagination (gabung games & apps agar lebih simpel) 
		
		preg_match_all('#/android/(?:games|apps)/page/(\d+)/?#i', $html, $pages);
		$page_numbers = array_map('intval', array_unique($pages[1] ?? []));
		$max_page = !empty($page_numbers) ? max($page_numbers) : 1;
		$max_page = max($max_page, (int)$paged);

        // ---------- BUILD RESULT ----------
        $items = [];

        foreach ($judul as $i => $title) {
            $items[] = [
                'title'   	=> trim(strip_tags($title)),
                'link'    	=> $link[$i]  ?? '',
                'image'   	=> $img[$i]   ?? '',
                'versi' 	=> $versi[$i] ?? '',
            ];
        }
		
		$count = count($items);

		if ($count === 0) {
			return $this->error('Didn\'t find any items even though the page was successfully fetched. The layout may have changed again.');
		}
		
		return [
			'items'            => $items,
			'total_page_game'  => $max_page,
			'total_page_app'   => $max_page,
			'current'          => (int)$paged,
			'count'            => $count,
			'status'           => 'success'
		];
		
    }	
         
	/**
	 * Fungsi Auto untuk 5play.org yang menggunakan result dari Code_5play
	 * 
	 * @param string $url URL target (contoh: https://5play.org/android/games/)
	 * @param object|null $externalCurl Instance external curl (opsional)
	 * @return array Hasil dengan format: status, count, items (title, url, image, version, mod), source
	 */
	public function Code_5play_Auto($url, $externalCurl = null)
	{
		// Panggil fungsi Code_5play yang sudah ada (dengan paged = 1 default)
		$result = $this->Code_5play($url, $externalCurl, 1);

		// Jika Code_5play gagal
		if (!isset($result['status']) || $result['status'] !== 'success') {
			$this->show_notice('error', 'Gagal mengambil data dari Code_5play: ' . ($result['message'] ?? 'Unknown error'));
			return [
				'status'  => 'error',
				'count'   => 0,
				'items'   => [],
				'source'  => $url
			];
		}

		$raw_items = $result['items'] ?? [];
		$items = [];

		foreach ($raw_items as $raw) {
			// Pisah version & mod (contoh pola umum di 5play: "1.2.3" atau "1.2.3 MOD" atau "1.2.3 + Data")
			$version_full = $raw['versi'] ?? 'Tidak terdeteksi';
			$version = $version_full;
			$mod = '';

			// Logika pemisahan (bisa diperluas sesuai pola yang sering muncul)
			if (stripos($version_full, 'MOD') !== false ||
				stripos($version_full, 'Unlimited') !== false ||
				stripos($version_full, 'Mega Mod') !== false ||
				stripos($version_full, '+ Data') !== false ||
				stripos($version_full, 'No Ads') !== false) {
				// Pisah dengan spasi atau tanda hubung sebagai delimiter umum
				$parts = preg_split('/\s+MOD|\s*\+\s*|\s*No Ads/i', $version_full, 2);
				$version = trim($parts[0] ?? $version_full);
				$mod = trim($parts[1] ?? '');
				if ($mod) {
					$mod = "MOD " . $mod; // tambah prefix agar jelas
				}
			}

			$items[] = [
				'title'   => html_entity_decode(trim($raw['title'] ?? ''), ENT_QUOTES | ENT_HTML5),
				'url'     => trim($raw['link'] ?? ''),
				'image'   => trim($raw['image'] ?? ''),
				'version' => trim($version),
				'mod'     => trim($mod),
			];
		}

		$count = count($items);
		$status = $count > 0 ? 'success' : 'warning';

		if ($status === 'warning') {
			$this->show_notice('warning', 'Some or all items are incomplete. The page structure may have changed again.');
		}

		return [
			'status'  => $status,
			'count'   => $count,
			'items'   => $items,
			'source'  => $url
		];
	}

	public function Code_5play_Auto1221($url, $externalCurl = null)
	{
		// Contoh URL yang diharapkan: https://5play.org/en/android/games/
		// 1. Pastikan library Simple HTML DOM tersedia
		if (!function_exists('file_get_html')) {
			require_once get_template_directory() . '/libs/addons/inc/dom.php';
		}

		$html_string = null;

		// 2. Prioritas utama: gunakan $this->scrapedo() (mekanisme bypass Anda)
		$status_code = $this->http_respon($url);
		$allowed = [200, 201];
		$blocked = [301, 302, 303, 307, 308, 403];

		if (in_array($status_code, $blocked) || !in_array($status_code, $allowed)) {
			$html_string = $this->scrapedo($url);
		} else {
			$html_string = $this->fast_get_content($url);
		}

		// 3. Fallback jika scrapedo gagal / konten terlalu pendek
		if (empty($html_string) || strlen(trim($html_string)) < 800) {
			$html_string = @file_get_html(
				$url,
				false,
				null,
				0,
				-1,
				true,  // force use file_get_contents
				true,  // use curl fallback
				DEFAULT_TARGET_CHARSET,
				false
			);

			if (!$html_string) {
				$this->show_notice('error', 'Gagal mengambil halaman 5play.org (kemungkinan Cloudflare / anti-bot)');
				return [
					'status' => 'error',
					'count' => 0,
					'items' => []
				];
			}
		}

		// 4. Parsing HTML
		$html = is_object($html_string) ? $html_string : str_get_html($html_string);
		if (!$html) {
			$this->show_notice('error', 'Gagal mem-parsing HTML dari 5play.org');
			return [
				'status' => 'error',
				'count' => 0,
				'items' => []
			];
		}

		$items = [];

		// 5. Coba temukan container daftar game (lebih fleksibel + prioritas XPath)
		$container = null;

		// XPath lebih recommended karena lebih presisi
		$xpath = $html->xpath ? $html->xpath : null; // Jika Simple HTML DOM support xpath (ext)

		if ($xpath) {
			// Beberapa kemungkinan XPath container (update sesuai struktur 2025-2026)
			$possible_xpaths = [
				'//div[contains(@class, "app-list") or contains(@class, "game-list") or contains(@class, "glist")]',
				'//div[contains(@class, "grid") or contains(@class, "row") or contains(@class, "items")]',
				'//main//div[contains(@class, "list") or contains(@class, "container")]',
				'//section[contains(@class, "content")]//div[contains(@class, "item")]'
			];

			foreach ($possible_xpaths as $xp) {
				$nodes = $xpath->query($xp);
				if ($nodes->length > 0) {
					$container = $html->find('xpath=' . $xp, 0); // konversi kembali ke simple dom jika perlu
					break;
				}
			}
		}

		// Fallback CSS jika XPath tidak jalan
		if (!$container) {
			$possible_selectors = [
				'div.glist.app-list',
				'div.app-list',
				'div.grid',
				'div.items-container',
				'div[class*="list"]',
				'main > div',
				'section.content'
			];

			foreach ($possible_selectors as $sel) {
				$container = $html->find($sel, 0);
				if ($container) break;
			}
		}

		if (!$container) {
			$html->clear();
			unset($html);
			$this->show_notice('warning', 'Couldn\'t find the app/game list block. The 5play site structure has changed significantly.');
			return [
				'status' => 'warning',
				'count' => 0,
				'items' => []
			];
		}

		// 6. Ambil semua item game/aplikasi
		$elements = $container->find('div.app-item, article.game-item, div.card, div.item, div[class*="card"], div[class*="item"], a[href*="/en/android/"]');

		foreach ($elements as $el) {
			// TITLE (prioritas XPath lalu CSS)
			$title = '';
			$title_el = $el->find('span.title, h3, .title, .name, a[title], .game-title', 0);
			if ($title_el) {
				$title = trim($title_el->plaintext);
			} else {
				// Coba XPath alternatif
				$title_nodes = $el->find('xpath=.//h3 | .//span[contains(@class,"title")] | .//div[contains(@class,"name")]', 0);
				if ($title_nodes) $title = trim($title_nodes->plaintext);
			}

			// LINK
			$link = '';
			$link_el = $el->find('a[href]', 0);
			if ($link_el) {
				$link = $link_el->href;
				if (!preg_match('#^https?://#i', $link)) {
					$link = 'https://5play.org' . (substr($link, 0, 1) === '/' ? '' : '/') . $link;
				}
			}

			// IMAGE (support lazy loading)
			$image = '';
			$img_el = $el->find('img[src], img[data-src]', 0);
			if ($img_el) {
				$image = $img_el->src ?: $img_el->getAttribute('data-src') ?: $img_el->getAttribute('data-lazy-src') ?: $img_el->getAttribute('data-original') ?: '';
				if ($image && !preg_match('#^https?://#i', $image)) {
					$image = 'https://5play.org' . (substr($image, 0, 1) === '/' ? '' : '/') . $image;
				}
			}

			// VERSION (biasanya di small text / span.version / div.meta)
			$version = '';
			$ver_el = $el->find('span.version, .version, small, div.meta, .info small, .version-info', 0);
			if ($ver_el) {
				$version_text = trim($ver_el->plaintext);
				if (preg_match('/\d+\.\d+(\.\d+)?/', $version_text, $m)) {
					$version = $m[0];
				} else {
					$version = $version_text;
				}
			}

			// MOD (MOD APK, MOD MENU, dll - biasanya di badge / span.tag / div.mod)
			$mod = '';
			$mod_el = $el->find('span.mod, .mod, .tag-mod, .badge-mod, div.mod-info, span[class*="mod"]', 0);
			if ($mod_el) {
				$mod = trim($mod_el->plaintext);
			} elseif (stripos($el->innertext, 'mod') !== false || stripos($el->innertext, 'hack') !== false) {
				$mod = 'MOD';
			}

			// Filter hanya item yang punya minimal title + link
			if (empty($title) || empty($link)) {
				continue;
			}

			$items[] = [
				'title'  => html_entity_decode(trim($title), ENT_QUOTES | ENT_HTML5),
				'url'    => $link,
				'image'  => $image,
				'version'=> trim($version),
				'mod'    => $mod,
			];
		}

		// 7. Cleanup
		$html->clear();
		unset($html);

		$count = count($items);
		$status = $count > 0 ? 'success' : 'warning';

		if ($status === 'warning') {
			$this->show_notice('warning', 'Some or all items are incomplete. The page structure may have changed again.');
		}

		return [
			'status' => $status,
			'count'  => $count,
			'items'  => $items,
			'source' => $url
		];
	}

	/**
	 * Fungsi Code_Apkdone dengan parameter limit
	 * 
	 * @param string $url URL target (contoh: https://apkdone.com/game/)
	 * @param object $Go_Curl Instance Go_Curl untuk helper (tidak digunakan di fungsi ini)
	 * @param int $limit Jumlah maksimal item yang ingin diekstrak (default: 0 = ambil semua)
	 * @param int $paged Halaman saat ini (untuk kompatibilitas pagination)
	 * @return array Result dengan items, count, dll
	 */
	public function Code_Apkdone($url, $Go_Curl, $limit = 0, $paged = 1)
	{
		// ==============================================
		// 1. Fetch HTML
		// ==============================================
		$context_options = [
			'http' => [
				'method'          => 'GET',
				'timeout'         => 15,
				'follow_location' => true,
				'header'          => implode("\r\n", [
					'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
					'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
					'Accept-Language: en-US,en;q=0.5',
					'Referer: https://www.google.com/',
				]),
			],
			'ssl' => [
				'verify_peer'      => false,
				'verify_peer_name' => false,
			]
		];

		$context = stream_context_create($context_options);
		$html_raw = @file_get_contents($url, false, $context);

		// Retry dengan UA berbeda jika gagal atau terlalu pendek
		if (empty($html_raw) || strlen($html_raw) < 50000) {
			$context_options['http']['header'] = implode("\r\n", [
				'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130 Safari/537.36',
				'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
				'Accept-Language: en-US,en;q=0.5',
				'Referer: https://www.google.com/',
			]);
			$context = stream_context_create($context_options);
			$html_raw = @file_get_contents($url, false, $context);
		}

		if (empty($html_raw) || strlen($html_raw) < 50000) {
			return $this->error('Gagal mengambil halaman lengkap. Panjang HTML hanya ' . strlen($html_raw ?? 0) . ' karakter.');
		}

		// ==============================================
		// 2. Parse dengan Simple HTML DOM
		// ==============================================
		$html = str_get_html($html_raw);
		if (!$html) {
			return $this->error('Gagal parse HTML dengan Simple HTML DOM.');
		}

		// ==============================================
		// 3. Ambil semua div.app-card
		// ==============================================
		$cards = $html->find('div.app-card');

		if (empty($cards) || count($cards) === 0) {
			$html->clear();
			unset($html);
			return $this->error('Tidak ditemukan elemen app-card.');
		}

		$items = [];
		$max_items = ($limit > 0) ? $limit : PHP_INT_MAX; // Jika limit=0, ambil semua

		foreach ($cards as $index => $card) {
			if ($index >= $max_items) {
				break; // Hentikan jika sudah mencapai limit
			}

			$title_a = $card->find('h3.app-card-title a', 0);
			$title = $title_a ? trim($title_a->plaintext) : 'Tidak terdeteksi';
			$link  = $title_a ? trim($title_a->href) : '';

			$img = $card->find('img.ratio-media', 0);
			$image = $img ? ($img->getAttribute('data-src') ?: $img->getAttribute('src') ?: '') : '';

			$meta_spans = $card->find('div.app-card-meta span.chip-text');
			$versi_parts = [];
			foreach ($meta_spans as $span) {
				$text = trim($span->plaintext);
				if ($text) $versi_parts[] = $text;
			}
			$versi = !empty($versi_parts) ? implode(' | ', $versi_parts) : 'Tidak terdeteksi';

			// Tambahkan hanya jika judul & link valid
			if ($title !== 'Tidak terdeteksi' && $link !== '') {
				$items[] = [
					'title' => $title,
					'link'  => $link,
					'image' => $image,
					'versi' => $versi,
				];
			}
		}

		// Bersihkan memory
		$html->clear();
		unset($html);

		// ==============================================
		// 4. Pagination & Result
		// ==============================================
		$max_page = 1; // Halaman tunggal saat ini
		$max_page = max($max_page, (int)$paged);

		$count = count($items);

		if ($count === 0) {
			return $this->error('Tidak ada item valid yang berhasil diekstrak (dari ' . count($cards) . ' card).');
		}

		return [
			'items'            => $items,
			'total_page_game'  => $max_page,
			'total_page_app'   => $max_page,
			'current'          => (int)$paged,
			'count'            => $count,
			'total_found'      => count($cards), // Info tambahan: total card di halaman
			'status'           => 'success'
		];
	}

	public function Code_Apkdone_Auto($url, $externalCurl = null)
	{
		// Panggil fungsi Code_Apkdone yang sudah working (limit 0 = ambil semua, atau sesuaikan)
		$result = $this->Code_Apkdone($url, $externalCurl, 0); // limit 0 = semua item

		// Jika Code_Apkdone gagal
		if (!isset($result['status']) || $result['status'] !== 'success') {
			$this->show_notice('error', 'Gagal mengambil data dari Code_Apkdone: ' . ($result['message'] ?? 'Unknown error'));
			return [
				'status'  => 'error',
				'count'   => 0,
				'items'   => [],
				'source'  => $url
			];
		}

		$raw_items = $result['items'] ?? [];
		$items = [];

		foreach ($raw_items as $raw) {
			// Pisah versi & mod (contoh sederhana: jika ada kata "Unlimited", "No Ads", "MOD", dll)
			$version_full = $raw['versi'] ?? 'Tidak terdeteksi';
			$version = $version_full;
			$mod = '';

			// Logika sederhana untuk pisah mod (bisa diperluas)
			if (stripos($version_full, 'Unlimited') !== false ||
				stripos($version_full, 'No Ads') !== false ||
				stripos($version_full, 'MOD') !== false ||
				stripos($version_full, 'Free Shopping') !== false) {
				$parts = explode('|', $version_full);
				$version = trim($parts[0] ?? $version_full); // versi biasanya di awal
				$mod = trim(implode(' | ', array_slice($parts, 1))); // sisanya mod
			}

			$items[] = [
				'title'   => html_entity_decode(trim($raw['title'] ?? ''), ENT_QUOTES | ENT_HTML5),
				'url'     => trim($raw['link'] ?? ''),
				'image'   => trim($raw['image'] ?? ''),
				'version' => trim($version),
				'mod'     => trim($mod),
			];
		}

		$count = count($items);
		$status = $count > 0 ? 'success' : 'warning';

		if ($status === 'warning') {
			$this->show_notice('warning', 'Some or all items are incomplete. The page structure may have changed again.');
		}

		return [
			'status'  => $status,
			'count'   => $count,
			'items'   => $items,
			'source'  => $url
		];
	}
 
	public function Code_Apkmody_Asli($url, $Go_Curl, $paged = 1) 
	{
		
		$apikey = "1afba4cc594383090bc026060d50823f";
		// Proxy ScraperAPI mode port (lebih stabil)
		$proxy = "http://scraperapi:" . $apikey . "@proxy-server.scraperapi.com:8001";

		// Tambahkan parameter ScraperAPI ke URL target (premium + country US)
		$scraper_params = http_build_query([
			'premium'      => 'true',
			'country_code' => 'us',
			// 'render'    => 'true',   // Uncomment jika halaman JS-heavy (tambah kredit)
		]);

		$proxied_url = $url . ($scraper_params ? '?' . $scraper_params : '');
		
			
		// Options untuk cURL (bisa dipakai di fast_get_content atau langsung)
		$options = [
			'timeout'        => 6,
			'connect_timeout' => 4,
			'follow_redirect' => true,
			'headers'        => [
				'User-Agent'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
				'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
				'Accept-Language' => 'en-US,en;q=0.5',
				'Referer'         => 'https://www.google.com/',
			],
			'proxy'          => $proxy,               // ← Proxy ScraperAPI
			'proxytype'      => CURLPROXY_HTTP,
			'ssl_verifypeer' => false,                // Sementara untuk lokal (hapus setelah fix cacert.pem)
			'ssl_verifyhost' => false,
		];
		
		// ===============================
		// HTTP STATUS CHECK
		// ===============================
		$status_code = $this->http_respon($url);
		$allowed_statuses = [200, 201];

		if (in_array($status_code, [301, 302, 303, 307, 308, 403])) {
		$html = $this->fast_get_content($proxied_url, $options);
		} else {
		$html = $this->fast_get_content($url, $options);
		}

		// ===============================
		// MAIN CONTAINER
		// ===============================
		$container_html = $this->match(
		'/<div class="flex-container">(.*?)<\/section>/ms',
		$html,
		1
		);

		// ===============================
		// BASIC DATA
		// ===============================
		$judul = $this->match_all('/<h2.*?>(.*?)<\/h2>/ms', $container_html, 1);
		$links = $this->match_all('/<a href="(.*?)".*?>/ms', $container_html, 1);
		$imgs  = $this->match_all('/<img.*?src="(.*?)".*?>/ms', $container_html, 1);

		// ===============================
		// VERSION + MOD PARSER
		// ===============================
		$sub_texts = $this->match_all(
		'/<div class="app-sub-text font-size__small color__gray truncate">(.*?)<\/div>/ms',
		$container_html,
		1
		);

		$versions = [];
		$mods     = [];

		foreach ($sub_texts as $sub_text) {

		if (preg_match(
			'/\s*(v?[0-9.\(\)\s-]+)\s*(.*?\s*)?<span class="app-genre">/ms',
			$sub_text,
			$m
		)) {
			$versions[] = trim($m[1]);
			$mod_raw 	= trim($m[2] ?? '');
			if ($mod_raw) {
			$mod_raw  = preg_replace('/^•\s*/', '', $mod_raw);
			$mod_list = preg_split('/\s*•\s*/', $mod_raw);
			$mods[]   = implode(', ', array_filter($mod_list));
			} else {
			$mods[] = '';
			}

		} else {
			$versions[] = '';
			$mods[]     = '';
		}
		}

		// ===============================
		// BUILD ITEMS (🔥 UTAMA 🔥)
		// ===============================
		$items = [];

		if (!empty($judul)) {
			foreach ($judul as $i => $title) {

				if (empty($title)) continue;

				$items[] = [
					'title'		=> trim(strip_tags($title)),
					'slug'		=> sanitize_title($title),
					'versi'		=> $versions[$i] ?? '',
					'mods'		=> $mods[$i] ?? '',
					'image'		=> $imgs[$i] ?? '',
					'link'		=> $links[$i] ?? '',
					'source'	=> 'apkmody',
					'page'		=> $paged,
					'scraped_at'	=> current_time('mysql'),
				];
			}
		}
		
		 // ================== 4. Pagination (gabung games & apps) ==================
		preg_match_all('#https?://apkmody\.com/(?:games|apps)/page/(\d+)["\']#i', $html, $pages);
		$page_numbers = array_map('intval', array_unique($pages[1] ?? []));
		$max_page = $page_numbers ? max($page_numbers) : 1;
		$max_page = max($max_page, (int)$paged);

		// ================== Hasil akhir ==================
		$count = count($items);
		if ($count < 3) {
			return $this->error("Only found {$count} items. Parsing may no longer match the latest structure.");
		}
		
		// ===============================
		// RETURN FINAL
		// ===============================
		return [
			'status_code' => $status_code,
			'paged'       => $paged,
			'total_page_game' => $max_page,
			'total_page_app'  => $max_page,
			'items'       => $items,
			'current'     => (int) $paged
		];
	}
	
	public function Code_Apkmody($url, $Go_Curl, $paged = 1)
	{
		$options = [
			'timeout'         => 6,
			'connect_timeout' => 4,
			'follow_redirect' => true,
			'headers'         => [
				'User-Agent'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
				'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
				'Accept-Language' => 'en-US,en;q=0.5',
				'Referer'         => 'https://www.google.com/',
			]
		];

		// ===============================
		// HTTP STATUS CHECK + BYPASS LOGIC
		// ===============================
		$status_code = $this->http_respon($url);
		$allowed_statuses = [200, 201];

		if (in_array($status_code, [301, 302, 303, 307, 308, 403])) {
			// Redirect atau forbidden → kemungkinan Cloudflare/protection → pakai bypass
			$html = $this->fetchWithCloudflareBypass($url);
		} else {
			// Status OK → coba ambil langsung (lebih cepat)
			$html = $this->fast_get_content($url, $options);

			// Fallback jika hasil terlalu pendek (mungkin challenge tersembunyi atau error)
			if (empty($html) || strlen($html) < 8000) {  // threshold dinaikkan karena halaman listing biasanya >10-15KB
				$html = $this->fetchWithCloudflareBypass($url);
			}
		}

		// Jika masih gagal setelah semua upaya
		if (empty($html) || strlen($html) < 8000) {
			return $this->error('Gagal memuat apkmody.com. Cloudflare atau struktur situs mungkin berubah. Cek log.');
		}

		// ===============================
		// MAIN CONTAINER
		// ===============================
		$container_html = $this->match(
			'/<div class="flex-container">(.*?)<\/section>/ms',
			$html,
			1
		);

		// Optional: Jika container tidak ketemu → situs mungkin redesign (peringatan)
		if (empty($container_html)) {
			error_log("Warning: flex-container tidak ditemukan di apkmody.com page $paged");
		}

		// ===============================
		// BASIC DATA
		// ===============================
		$judul = $this->match_all('/<h2.*?>(.*?)<\/h2>/ms', $container_html, 1);
		$links = $this->match_all('/<a href="(.*?)".*?>/ms', $container_html, 1);
		$imgs  = $this->match_all('/<img.*?src="(.*?)".*?>/ms', $container_html, 1);

		// ===============================
		// VERSION + MOD PARSER
		// ===============================
		$sub_texts = $this->match_all(
			'/<div class="app-sub-text font-size__small color__gray truncate">(.*?)<\/div>/ms',
			$container_html,
			1
		);

		$versions = [];
		$mods = [];
		foreach ($sub_texts as $sub_text) {
			if (preg_match(
				'/\s*(v?[0-9.\(\)\s-]+)\s*(.*?\s*)?<span class="app-genre">/ms',
				$sub_text,
				$m
			)) {
				$versions[] = trim($m[1]);
				$mod_raw = trim($m[2] ?? '');
				if ($mod_raw) {
					$mod_raw = preg_replace('/^•\s*/', '', $mod_raw);
					$mod_list = preg_split('/\s*•\s*/', $mod_raw);
					$mods[] = implode(', ', array_filter($mod_list));
				} else {
					$mods[] = '';
				}
			} else {
				$versions[] = '';
				$mods[] = '';
			}
		}

		// ===============================
		// BUILD ITEMS (🔥 UTAMA 🔥)
		// ===============================
		$items = [];
		if (!empty($judul)) {
			foreach ($judul as $i => $title) {
				if (empty($title)) continue;

				// Pastikan link & image sesuai index (hindari offset error)
				$link = $links[$i] ?? '';
				$image = $imgs[$i] ?? '';

				$items[] = [
					'title'      => trim(strip_tags($title)),
					'slug'       => sanitize_title($title),
					'versi'      => $versions[$i] ?? '',
					'mods'       => $mods[$i] ?? '',
					'image'      => $image,
					'link'       => $link,
					'source'     => 'apkmody',
					'page'       => (int) $paged,
					'scraped_at' => current_time('mysql'),
				];
			}
		}

		// ================== Pagination (gabung games & apps) ==================
		preg_match_all('#https?://apkmody\.com/(?:games|apps)/page/(\d+)["\']#i', $html, $pages);
		$page_numbers = array_map('intval', array_unique($pages[1] ?? []));
		$max_page = $page_numbers ? max($page_numbers) : 1;
		$max_page = max($max_page, (int)$paged);

		// ================== Hasil akhir ==================
		$count = count($items);
		if ($count < 3) {
			return $this->error("Hanya menemukan {$count} item. Parsing mungkin tidak lagi cocok dengan struktur terbaru apkmody.com.");
		}

		// ===============================
		// RETURN FINAL
		// ===============================
		return [
			'status_code'     => $status_code,
			'paged'           => (int) $paged,
			'total_page_game' => $max_page,
			'total_page_app'  => $max_page,
			'items'           => $items,
			'current'         => (int) $paged
		];
	}

    public function Code_Apkmody_Auto($url, $externalCurl = null) 
	{        
        // 1. Cek HTTP status        
		$status_code = $this->http_respon($url);	 
		$allowed_statuses = [200, 201]; // or whatever indicates success
		if (in_array($status_code, [301, 302, 303, 307, 308, 403])) {
			// Likely blocked or redirected — use scraper bypass
			$html = $this->scrapedo($url);				
			//$html = $this->fast_get_content($url);
		} elseif (in_array($status_code, $allowed_statuses)) {
			//$html = $this->Go_Curl->scrape_sitex($url);
			$html = $this->fast_get_content($url);
		} else {
			// Optional: handle other errors (e.g. 404, 500, etc.)
			//$html = $this->Go_Curl->scrape_sitex($url);
			$html = $this->fast_get_content($url);
		}
		//print_r($status_code);
		

        if (empty($html) || strlen($html) < 500) {
            $this->output_error_url('Failed to fetch content from ' . esc_url($url) . ' (status: ' . $status_code . '), Please <a href=\'/wp-admin/admin.php?page=sc-auto-post&ai_force_reset=1\'>Click Reset</a> Importer On 🚨 Admin Bar.');
            return [
                'status' => 'error',
                'count'  => 0,
                'items'  => []
            ];
        }

        // 2. Ambil container utama
        $container = $this->match('/<div class="flex-container">(.*?)<\/section>/ms', $html, 1);
        if (empty($container)) {
            $this->output_error_url('The site structure may have changed. or Blocked by Cloudflare., Please <a href=\'/wp-admin/admin.php?page=sc-auto-post&ai_force_reset=1\'>Click Reset</a> Importer On 🚨 Admin Bar.');
            return [
                'status' => 'error',
                'count'  => 0,
                'items'  => []
            ];
        }

        // 3. Ekstrak data dasar
        $judul = $this->match_all('/<h[23][^>]*>(.*?)<\/h[23]>/ms', $container, 1); // support h2 & h3
        $link  = $this->match_all('/<a[^>]+href=["\'](.*?)["\']/ms', $container, 1);
        $img   = $this->match_all('/<img[^>]+src=["\'](.*?)["\']/ms', $container, 1);

        // 4. Parsing versi & mod (lebih robust)
        $sub_texts = $this->match_all('/<div class="app-sub-text font-size__small color__gray truncate">(.*?)<\/div>/ms', $container, 1);

        $versi = [];
        $mods  = [];

        foreach ($sub_texts as $sub) {
            $sub = trim($sub);

            // Pattern: versi (v1.2.3 atau 1.0.0) lalu bagian mod sebelum <span class="app-genre">
            if (preg_match('/\s*(v?[0-9][0-9a-zA-Z.\(\)\s-]*)\s*(.*?)\s*<span class="app-genre">/ms', $sub, $m)) {
                $versi[] = trim($m[1]);
                $mod_part = trim($m[2]);

                // Bersihkan & split mods (• sebagai pemisah)
                $mod_part = preg_replace('/^•\s*/', '', $mod_part);
                $mod_list = preg_split('/\s*•\s*/', $mod_part);
                $mod_list = array_filter($mod_list, 'strlen');
                $mods[] = implode(', ', $mod_list);
            } else {
                $versi[] = '';
                $mods[]  = '';
            }
        }

        // 5. Hitung jumlah minimal yang valid
        $count = min(
            count($judul),
            count($link),
            count($img),
            count($versi),
            count($mods)
        );

        $items = [];
        for ($i = 0; $i < $count; $i++) {
            $title_clean = trim(html_entity_decode(strip_tags($judul[$i]), ENT_QUOTES | ENT_HTML5));
            $href_clean  = trim($link[$i]);
            $img_clean   = trim($img[$i]);

            if (empty($title_clean) || empty($href_clean)) {
                continue;
            }

            $items[] = [
                'title' => $title_clean,
                'url'   => $href_clean,
                'image' => $img_clean,
                'versi' => $versi[$i] ?? '',
                'mods'    => $mods[$i] ?? '',
            ];
        }

        $final_count = count($items);

        return [
            'status' => $final_count > 0 ? 'success' : 'warning',
            'count'  => $final_count,
            'items'  => $items,
            'source' => $url,
            'debug'  => [ // optional – hapus jika tidak perlu
                'status_code' => $status_code,
                'html_length' => strlen($html),
                'container_length' => strlen($container)
            ]
        ];
    } 
	
    public function Code_Getmodsapk($url, $Go_Curl, $paged = 1)
	{         
		$options = [
			'timeout'         => 6,
			'connect_timeout' => 4,
			'follow_redirect' => true,
			'headers'         => [
				'User-Agent'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
				'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
				'Accept-Language' => 'en-US,en;q=0.5',
				'Referer'         => 'https://www.google.com/',
			]
		];

        // 1. Cek HTTP status        
		$status_code = $this->http_respon($url);	 
		$allowed_statuses = [200, 201]; // or whatever indicates success
		if (in_array($status_code, [301, 302, 303, 307, 308, 403])) {
			// Likely blocked or redirected — use scraper bypass
			$html = $this->scrapedo($url);				
			//$html = $this->fast_get_content($url);
		} elseif (in_array($status_code, $allowed_statuses)) {
			//$html = $this->Go_Curl->scrape_sitex($url);
			$html = $this->fast_get_content($url, $options);
		} else {
			// Optional: handle other errors (e.g. 404, 500, etc.)
			//$html = $this->Go_Curl->scrape_sitex($url);
			$html = $this->fast_get_content($url, $options);
		}
		//print_r($status_code);		

		if (empty($html) || strlen($html) < 3500) {
			return $this->error('GFailed to load getmodsapk.com. Cloudflare is very strict these days.');
		}

        // ===============================
        // MAIN CONTAINER
        // ===============================
        $container_html = $this->match(
            '/<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 my-2">(.*?)<\/section>/ms',
            $html,
            1
        );

        // ===============================
        // BASIC DATA
        // ===============================
        $judul = $this->match_all(
            '/<h3 class="font-semibold[^>]*">(.*?)<\/h3>/ms',
            $container_html,
            1
        );

        $links = $this->match_all(
            '/<a href="(https:\/\/getmodsapk\.com\/[^"]*)"[^>]*class="[^"]*rounded-xl[^"]*"/ms',
            $container_html,
            1
        );

        $images = $this->match_all(
            '/<img[^>]*src="(https:\/\/getmodsapk\.com\/storage\/[^"]*)"[^>]*class="[^"]*rounded-2xl[^"]*"/ms',
            $container_html,
            1
        );

        $versions = $this->match_all(
            '/<span class="text-xs text-gray-600 dark:text-gray-300">(v?[0-9.\w]+)<\/span>/ms',
            $container_html,
            1
        );

        // ===============================
        // MOD FEATURES
        // ===============================
        $mods_raw = $this->match_all(
            '/<span class="inline-flex items-center gap-1 text-xs"[^>]*>\s*<svg[^>]*>.*?<\/svg>\s*(.*?)<\/span>/ms',
            $container_html,
            1
        );
        $mods = array_map('trim', $mods_raw);

        // ===============================
        // SIZE
        // ===============================
        $size_raw = $this->match_all(
            '/<span class="text-gray-600 dark:text-gray-400">Size:<\/span>\s*<span>(.*?)<\/span>/ms',
            $container_html,
            1
        );
        $sizes = array_map('trim', $size_raw);

        // ===============================
        // BUILD ITEMS
        // ===============================
        $items = [];

        if (!empty($judul)) {
            foreach ($judul as $i => $title) {

                if (empty($title)) continue;

                $items[] = [
                    'title'      => trim(strip_tags($title)),
                    'slug'       => sanitize_title($title),
                    'versi'    => $versions[$i] ?? '',
                    'mods'       => $mods[$i] ?? '',
                    'size'       => $sizes[$i] ?? '',
                    'image'      => $images[$i] ?? '',
                    'link'       => $links[$i] ?? '',
                    'source'     => 'getmodsapk',
                    'page'       => (int) $paged,
                    'scraped_at' => current_time('mysql'),
                ];
            }
        }

        preg_match_all('#https?://getmodsapk\.com/(?:games|apps)\?page=(\d+)["\']#i', $html, $pages);
		$page_numbers = array_map('intval', array_unique($pages[1] ?? []));
		$max_page = $page_numbers ? max($page_numbers) : 1;
		$max_page = max($max_page, (int)$paged);
		
			
		// ================== Hasil akhir ==================
		$count = count($items);
		if ($count < 3) {
			return $this->error("Only found {$count} items. Parsing may no longer match the site's latest structure.");
		}
		
        // ===============================
        // RETURN
        // ===============================
        return [
            'status_code' => $status_code,
            'paged'       => (int) $paged, 
            'items'       => $items,
			'total_page_game' => $max_page,
			'total_page_app'  => $max_page,
			'current'     => (int) $paged
        ];
    }
	
	public function Code_Getmodsapk_Asli($url, $Go_Curl, $paged = 1)
	{
		$options = [
			'timeout'         => 6,
			'connect_timeout' => 4,
			'follow_redirect' => true,
			'headers'         => [
				'User-Agent'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
				'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
				'Accept-Language' => 'en-US,en;q=0.5',
				'Referer'         => 'https://www.google.com/',
			]
		];

		// 1. Cek HTTP status terlebih dahulu
		$status_code = $this->http_respon($url);
		$allowed_statuses = [200, 201];

		if (in_array($status_code, [301, 302, 303, 307, 308, 403])) {
			// Redirect atau forbidden → kemungkinan Cloudflare atau block → gunakan bypass
			$html = $this->fetchWithCloudflareBypass($url);
		} elseif (in_array($status_code, $allowed_statuses)) {
			// Status OK → coba ambil langsung dulu (lebih cepat)
			$html = $this->fast_get_content($url, $options);

			// Jika gagal atau terlalu pendek (mungkin challenge tersembunyi), fallback ke bypass
			if (empty($html) || strlen($html) < 8000) {
				$html = $this->fetchWithCloudflareBypass($url);
			}
		} else {
			// Status lain (404, 500, dll) → langsung coba bypass
			$html = $this->fetchWithCloudflareBypass($url);
		}

		// Jika masih gagal setelah bypass
		if (empty($html) || strlen($html) < 8000) {  // naikkan threshold karena situs kadang lebih ringan
			return $this->error('Gagal memuat getmodsapk.com. Cloudflare atau struktur situs mungkin berubah. Cek log untuk detail.');
		}

		// ===============================
		// MAIN CONTAINER
		// ===============================
		$container_html = $this->match(
			'/<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 my-2">(.*?)<\/section>/ms',
			$html,
			1
		);

		// Jika container tidak ketemu → situs mungkin sudah ubah struktur (peringatan)
		if (empty($container_html)) {
			// Optional: log warning
			error_log("Warning: Grid container tidak ditemukan di getmodsapk.com page $paged");
		}

		// ===============================
		// BASIC DATA (tetap gunakan regex lama, tapi monitor perubahan)
		// ===============================
		$judul = $this->match_all(
			'/<h3 class="font-semibold[^>]*">(.*?)<\/h3>/ms',
			$container_html,
			1
		);
		$links = $this->match_all(
			'/<a href="(https:\/\/getmodsapk\.com\/[^"]*)"[^>]*class="[^"]*rounded-xl[^"]*"/ms',
			$container_html,
			1
		);
		$images = $this->match_all(
			'/<img[^>]*src="(https:\/\/getmodsapk\.com\/storage\/[^"]*)"[^>]*class="[^"]*rounded-2xl[^"]*"/ms',
			$container_html,
			1
		);
		$versions = $this->match_all(
			'/<span class="text-xs text-gray-600 dark:text-gray-300">(v?[0-9.\w]+)<\/span>/ms',
			$container_html,
			1
		);

		// MOD FEATURES
		$mods_raw = $this->match_all(
			'/<span class="inline-flex items-center gap-1 text-xs"[^>]*>\s*<svg[^>]*>.*?<\/svg>\s*(.*?)<\/span>/ms',
			$container_html,
			1
		);
		$mods = array_map('trim', $mods_raw);

		// SIZE
		$size_raw = $this->match_all(
			'/<span class="text-gray-600 dark:text-gray-400">Size:<\/span>\s*<span>(.*?)<\/span>/ms',
			$container_html,
			1
		);
		$sizes = array_map('trim', $size_raw);

		// ===============================
		// BUILD ITEMS
		// ===============================
		$items = [];
		if (!empty($judul)) {
			foreach ($judul as $i => $title) {
				if (empty($title)) continue;
				$items[] = [
					'title'      => trim(strip_tags($title)),
					'slug'       => sanitize_title($title),
					'versi'      => $versions[$i] ?? '',
					'mods'       => $mods[$i] ?? '',
					'size'       => $sizes[$i] ?? '',
					'image'      => $images[$i] ?? '',
					'link'       => $links[$i] ?? '',
					'source'     => 'getmodsapk',
					'page'       => (int) $paged,
					'scraped_at' => current_time('mysql'),
				];
			}
		}

		// Pagination detection
		preg_match_all('#https?://getmodsapk\.com/(?:games|apps)\?page=(\d+)["\']#i', $html, $pages);
		$page_numbers = array_map('intval', array_unique($pages[1] ?? []));
		$max_page = $page_numbers ? max($page_numbers) : 1;
		$max_page = max($max_page, (int)$paged);

		// ================== Hasil akhir ==================
		$count = count($items);
		if ($count < 3) {
			return $this->error("Hanya menemukan {$count} item. Struktur situs getmodsapk.com mungkin sudah berubah. Perlu update regex.");
		}

		return [
			'status_code'       => $status_code,
			'paged'             => (int) $paged,
			'items'             => $items,
			'total_page_game'   => $max_page,
			'total_page_app'    => $max_page,
			'current'           => (int) $paged
		];
	}

    public function Code_Getmodsapk_Auto($url, $externalCurl = null)
    {
        //$curl = $externalCurl ?? $this->Go_Curl;
        
        
        // 1. Cek HTTP status   
		$options = [
			'timeout'         => 6,
			'connect_timeout' => 4,
			'follow_redirect' => true,
			'headers'         => [
				'User-Agent'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
				'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
				'Accept-Language' => 'en-US,en;q=0.5',
				'Referer'         => 'https://www.google.com/',
			]
		];	

        $status_code = $this->http_respon($url);

        $allowed_statuses = [200, 201];
        $blocked_or_redirect = [301, 302, 303, 307, 308, 403];

        if (in_array($status_code, $blocked_or_redirect)) {
            // Mungkin kena block/redirect → pakai bypass
            $html = $this->scrapedo($url);
        } elseif (in_array($status_code, $allowed_statuses)) {
            $html = $this->fast_get_content($url, $options);
        } else {
            // Fallback untuk status lain (404, 500, dll)
            $html = $this->fast_get_content($url, $options);
        }
 
        if (empty($html) || strlen(trim($html)) < 300) {
            $this->output_error_url("Failed to fetch content from {$url} (status: {$status_code}), Please <a href='/wp-admin/admin.php?page=sc-auto-post&ai_force_reset=1'>Click Reset</a> Importer On 🚨 Admin Bar.");
            return [
                'status' => 'error',
                'count'  => 0,
                'items'  => []
            ];
        }

        // 2. Ambil container grid utama
        $container_html = $this->match(
            '/<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 my-2">(.*?)<\/section>/ms',
            $html,
            1
        );

        if (empty($container_html)) {
            $this->output_error_url('Container not found. The site structure may have changed.');
            return [
                'status' => 'error',
                'count'  => 0,
                'items'  => []
            ];
        }

        // 3. Ekstrak data per item
        $judul = $this->match_all('/<h3 class="font-semibold[^>]*">(.*?)<\/h3>/ms', $container_html, 1);
        $link  = $this->match_all('/<a href="(https:\/\/getmodsapk\.com\/[^"]*)"[^>]*class="[^"]*rounded-xl[^"]*"/ms', $container_html, 1);
        $img   = $this->match_all('/<img[^>]*src="(https:\/\/getmodsapk\.com\/storage\/[^"]*)"[^>]*class="[^"]*rounded-2xl[^"]*"/ms', $container_html, 1);
        $versi = $this->match_all('/<span class="text-xs text-gray-600 dark:text-gray-300">(v?[0-9.\w]+)<\/span>/ms', $container_html, 1);
        $mods_raw = $this->match_all('/<span class="inline-flex items-center gap-1 text-xs"[^>]*>\s*<svg[^>]*>.*?<\/svg>\s*(.*?)<\/span>/ms', $container_html, 1);
        $size_raw = $this->match_all('/<span class="text-gray-600 dark:text-gray-400">Size:<\/span>\s*<span>(.*?)<\/span>/ms', $container_html, 1);

        $mods = array_map('trim', $mods_raw);
        $size = array_map('trim', $size_raw);

        // 4. Sinkronkan jumlah minimal (judul & link wajib)
        $count = min(count($judul), count($link));

        $items = [];
        for ($i = 0; $i < $count; $i++) {
            $title = trim(html_entity_decode(strip_tags($judul[$i] ?? ''), ENT_QUOTES | ENT_HTML5));
            $href  = trim($link[$i] ?? '');
            $image = trim($img[$i] ?? '');

            if (empty($title) || empty($href)) {
                continue;
            }

            $items[] = [
                'title'   => $title,
                'url'     => $href,      // pastikan full URL
                'image'   => $image,
                'versi'   => $versi[$i] ?? '',
                'mods'    => $mods[$i] ?? '',
                'size'    => $size[$i] ?? '',
            ];
        }

        $final_count = count($items);

        $status = $final_count > 0 ? 'success' : 'warning';

        if ($status === 'warning' && $count > 0) {
            $this->output_error_url('Some items were found but the title/link is empty after filter.');
        }

        return [
            'status' => $status,
            'count'  => $final_count,
            'items'  => $items,
            'source' => $url,
            // optional debug (hapus jika tidak perlu)
            'debug'  => [
                'status_code'      => $status_code,
                'html_length'      => strlen($html),
                'container_length' => strlen($container_html)
            ]
        ];
    }
    
	public function Code_Liteapks($url, $Go_Curl, $paged = 1) 
	{
		$options = [
			'timeout'         => 6,
			'connect_timeout' => 4,
			'follow_redirect' => true,
			'headers'         => [
				'User-Agent'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
				'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
				'Accept-Language' => 'en-US,en;q=0.5',
				'Referer'         => 'https://www.google.com/',
			]
		];

        // 1. Cek HTTP status        
		$status_code = $this->http_respon($url);	 
		$allowed_statuses = [200, 201]; // or whatever indicates success
		if (in_array($status_code, [301, 302, 303, 307, 308, 403])) {
			// Likely blocked or redirected — use scraper bypass
			$html = $this->scrapedo($url);				
			//$html = $this->fast_get_content($url);
		} elseif (in_array($status_code, $allowed_statuses)) {
			//$html = $this->Go_Curl->scrape_sitex($url);
			$html = $this->fast_get_content($url, $options);
		} else {
			// Optional: handle other errors (e.g. 404, 500, etc.)
			//$html = $this->Go_Curl->scrape_sitex($url);
			$html = $this->fast_get_content($url, $options);
		}
		//print_r($status_code);
		
		if (empty($html) || strlen($html) < 3500) {
			return $this->error('Failed to fetch page liteapks.com. Cloudflare is being very strict these days.');
		}

		if (empty($html)) {
			return ['status_code' => $status_code, 'paged' => (int)$paged, 'items' => [], 'total_page_game' => 1, 'total_page_app' => 1, 'current' => (int)$paged];
		}

		// MAIN CONTAINER – keep, seems stable
		$container_html = $this->match('/<div class="row">(.*?)<nav class=\'nav-pagination\'>/ms', $html, 1);
		
		if (empty($container_html)) {
			// Fallback: try broader container if row/nav changed
			$container_html = $this->match('/<main[^>]*>(.*?)<\/main>/ms', $html, 1) ?: $html;
		}

		// CARD BLOCKS – more flexible pattern (match common card wrappers)
		$cards = $this->match_all(
			'/<div class="[^"]*col-(?:lg|md|sm|xl)-[346][^"]*"[^>]*>.*?<a[^>]+class="[^"]*archive-post[^"]*"[^>]*>.*?<\/a>.*?<\/div>/ms',
			$container_html,
			1
		);

		if (empty($cards)) {
			// Very broad fallback – find all archive-post links and their parents
			$cards = $this->match_all('/<a[^>]+class="[^"]*archive-post[^"]*"[^>]*>.*?<\/a>/ms', $container_html, 0);
		}

		$items = [];
		foreach ($cards as $card) {
			// TITLE (robust)
			preg_match('/<h[3-6][^>]*>(.*?)<\/h[3-6]>/ms', $card, $t);
			$title = trim(strip_tags($t[1] ?? ''));
			if ($title === '') continue;

			// LINK (absolute or relative → make absolute if needed)
			preg_match('/href=["\']([^"\']+\.html)["\']/i', $card, $l);
			$link = $l[1] ?? '';
			if ($link && !preg_match('#^https?://#', $link)) {
				$link = rtrim($base_url, '/') . '/' . ltrim($link, '/');
			}

			// IMAGE (first src, prefer data-src or srcset if lazy-loaded)
			// IMAGE – prioritas: src dulu, lalu data-src jika ada, lalu ambil dari srcset yang pertama/terkecil
			preg_match('/<img[^>]+(?:src|data-src)=["\']([^"\']+)["\']/i', $card, $i_src);
			$image = $i_src[1] ?? '';

			// Jika src kosong, fallback ke srcset (ambil yang pertama)
			if (empty($image)) {
				preg_match('/srcset=["\']([^"\']+)["\']/i', $card, $i_srcset);
				if (!empty($i_srcset[1])) {
					// Ambil URL pertama dari srcset
					$srcset_parts = explode(',', $i_srcset[1]);
					$first_src = trim(explode(' ', $srcset_parts[0])[0] ?? '');
					$image = $first_src;
				}
			}

			$image = trim($image);

			// VERSION & SIZE – looser pattern, don't rely on exact SVG
			preg_match(
				'/<span class="align-middle">([^<]+)<\/span>.*?\+\s*<\/span>.*?<span class="align-middle">([^<]+)<\/span>/ms',
				$card,
				$vs
			);
			$version = trim($vs[1] ?? '');
			$size    = trim($vs[2] ?? '');

			// MODS – capture after any icon until next tag or end
			preg_match('/(?:Unlimited|Mod|Free|No Ads|GOD|Unlocked)[^<]+/i', $card, $mod); // keyword-based fallback
			if (empty($mod[0])) {
				preg_match('/<span class="align-middle">\s*([^<]+?)\s*<\/span>(?![^<]*\+)/ms', $card, $mod);
			}
			$mods = trim($mod[1] ?? $mod[0] ?? '');

			$items[] = [
				'title'  => $title,
				'slug'   => strtolower(trim(preg_replace('/[^a-z0-9]+/i', '-', $title), '-')),
				'versi'  => $version,
				'size'   => $size,
				'mods'   => $mods,
				'image'  => $image,
				'link'   => $link,
				'source' => 'liteapks',
				'page'   => (int)$paged
			];
		}
		
		preg_match_all('#/(?:games|apps)/page/(\d+)/?#i', $html, $pages);
		$page_numbers = array_map('intval', array_unique($pages[1] ?? []));
		$max_page = $page_numbers ? max($page_numbers) : 1;
		$max_page = max($max_page, (int)$paged);
		
		$count = count($items);
		if ($count < 3) {
			return $this->error("Only found {$count} items. Parsing may no longer match the latest structure.");
		}
		
		return [
			'status_code'     => $status_code,
			'paged'           => (int)$paged,
			'items'           => $items,
			'total_page_game' => $max_page,
			'total_page_app'  => $max_page,
			'current'         => (int)$paged
		];
	}

	public function Code_Liteapks_Auto($url, $externalCurl = null)
	{
        // 1. Cek HTTP status   
		$options = [
			'timeout'         => 6,
			'connect_timeout' => 4,
			'follow_redirect' => true,
			'headers'         => [
				'User-Agent'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
				'Accept'          => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
				'Accept-Language' => 'en-US,en;q=0.5',
				'Referer'         => 'https://www.google.com/',
			]
		];	
		
		$status_code = $this->http_respon($url);	 
		$allowed_statuses = [200, 201]; // or whatever indicates success
		if (in_array($status_code, [301, 302, 303, 307, 308, 403])) {
			// Likely blocked or redirected — use scraper bypass
			$html = $this->scrapedo($url);				
			//$html = $this->fast_get_content($url);
		} elseif (in_array($status_code, $allowed_statuses)) {
			//$html = $this->Go_Curl->scrape_sitex($url);
			$html = $this->fast_get_content($url, $options);
		} else {
			// Optional: handle other errors (e.g. 404, 500, etc.)
			//$html = $this->Go_Curl->scrape_sitex($url);
			$html = $this->fast_get_content($url, $options);
		}
		//print_r($status_code);

		if (empty($html) || strlen(trim($html)) < 500) {
			$this->output_error_url("Failed to fetch content from {$url} (status: {$status_code}), Please <a href='/wp-admin/admin.php?page=sc-auto-post&ai_force_reset=1'>Click Reset</a> Importer On 🚨 Admin Bar.");
			return ['status' => 'error', 'count' => 0, 'items' => []];
		}

		// 2. Ambil blok utama daftar (fallback jika nav-pagination berubah)
		preg_match('/<div class="row">(.*?)(?:<nav class=\'nav-pagination\'>|<\/main>|<\/section>)/ms', $html, $m);
		$container_html = $m[1] ?? '';

		if (empty($container_html)) {
			$this->output_error_url('The main list block (row) was not found. The structure may have changed.');
			return ['status' => 'error', 'count' => 0, 'items' => []];
		}

		// 3. Ekstrak semua item secara lebih fleksibel (per col-*)
		preg_match_all('/<div class="col-12 col-md-6 col-xl-4 mb-3">(.*?)<\/div>\s*<\/div>/ms', $container_html, $item_blocks, PREG_SET_ORDER);

		$items = [];
		foreach ($item_blocks as $block) {
			$block_html = $block[1] ?? '';

			// Judul
			preg_match('/<h3 class="h6 font-weight-semibold[^>]*">(.*?)<\/h3>/ms', $block_html, $judul_m);
			$title = trim(html_entity_decode(strip_tags($judul_m[1] ?? ''), ENT_QUOTES | ENT_HTML5));

			// Link
			preg_match('/<a class="text-body[^>]*archive-post" href="([^"]+\.html)"/ms', $block_html, $link_m);
			$link_url = trim($link_m[1] ?? '');

			// Gambar (ambil src utama, bukan srcset)
			preg_match('/<img[^>]+src="([^"]+)"[^>]+class="[^"]*wp-post-image"/ms', $block_html, $img_m);
			$image_url = trim($img_m[1] ?? '');

			if (empty($title) || empty($link_url)) {
				continue;
			}

			// Versi + Size (SVG viewBox 576 512)
			preg_match('/<svg[^>]+viewBox="0 0 576 512"[^>]*>.*?<\/svg>\s*<span[^>]*>([^<]+)<\/span>\s*<span[^>]*>\s*\+\s*<\/span>\s*<span[^>]*>([^<]+)<\/span>/ms', $block_html, $versi_size);
			$version = trim($versi_size[1] ?? '');
			$size    = trim($versi_size[2] ?? '');

			// Mods (SVG viewBox 512 512 – wrench)
			preg_match('/<svg[^>]+viewBox="0 0 512 512"[^>]*>.*?<\/svg>\s*<span[^>]*>([^<]+)<\/span>/ms', $block_html, $mods_m);
			$mods_text = trim($mods_m[1] ?? '');

			$items[] = [
				'title'   => $title,
				'url'     => $link_url,          // sudah full URL https://liteapks.com/...
				'image'   => $image_url,         // https://liteapks.com/wp-content/uploads/... .webp
				'versi' => $version,
				'size'    => $size,
				'mods'    => $mods_text,
			];
		}

		$count = count($items);

		$status = $count > 0 ? 'success' : 'warning';

		if ($status === 'warning') {
			$this->output_error_url('No valid items found. Check if the regex needs to be adjusted again.');
		}

		return [
			'status' => $status,
			'count'  => $count,
			'items'  => $items,
			'source' => $url,
			'debug'  => [
				'status_code'      => $status_code,
				'total_blocks'     => count($item_blocks),
				'html_length'      => strlen($html)
			]
		];
	}
 
	
}
