<?php
/**
 * Zipwp Images Script
 *
 * @since 1.0.0
 * @package Zipwp Images Script
 */

namespace ZipWP_Images\Classes;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Ai_Builder
 */
class Zipwp_Images_Script {
	/**
	 * Instance
	 *
	 * @access private
	 * @var object Class Instance.
	 * @since 1.0.0
	 */
	private static $instance = null;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 */
	public function __construct() {
		add_action( 'admin_enqueue_scripts', array( $this, 'editor_load_scripts' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'bb_editor_load_scripts' ) );
		add_action( 'elementor/editor/before_enqueue_scripts', array( $this, 'editor_load_scripts' ) );
	}

	/**
	 * Initiator
	 *
	 * @since 1.0.0
	 * @return object initialized object of class.
	 */
	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Load script for block editor and elementor editor.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function editor_load_scripts(): void {

		if ( ! is_admin() ) {
			return;
		}

		$this->load_script();
	}

	/**
	 * Load script for block BB editor.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function bb_editor_load_scripts(): void {

		if ( class_exists( 'FLBuilderModel' ) && \FLBuilderModel::is_builder_active() || is_customize_preview() ) {
			$this->load_script();
		}
	}

	/**
	 * Load all the required files in the importer.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function load_script(): void {

		// Introduces a filter to exclude certain post types from the plugin.
		$exclude_post_types = apply_filters( 'zipwp_images_excluded_post_types', array( 'sureforms_form' ) );
		if ( ! function_exists( 'get_current_screen' ) ) {
			require_once ABSPATH . '/wp-admin/includes/screen.php';
		}
		$current_screen = get_current_screen();

		if ( is_object( $current_screen ) ) {
			if ( in_array( $current_screen->post_type, $exclude_post_types, true ) ) {
				return;
			}
		} elseif ( ! isset( $_GET['fl_builder'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Fetching GET parameter, no nonce associated with this action.
			return;
		}

		// Enqueue JS.
		wp_enqueue_script( 'zipwp-images-script', ZIPWP_IMAGES_URL . 'dist/main.js', array( 'jquery', 'media-views', 'react', 'wp-element', 'wp-api-fetch' ), ZIPWP_IMAGES_VER, true );

		$data = apply_filters(
			'zipwp_images_vars',
			array(
				'ajaxurl'              => esc_url( admin_url( 'admin-ajax.php' ) ),
				'asyncurl'             => esc_url( admin_url( 'async-upload.php' ) ),
				'is_customize_preview' => is_customize_preview(),
				'is_bb_active'         => class_exists( 'FLBuilderModel' ),
				'is_brizy_active'      => class_exists( 'Brizy_Editor_Post' ),
				'is_elementor_active'  => did_action( 'elementor/loaded' ),
				'is_elementor_editor'  => did_action( 'elementor/loaded' ) && class_exists( '\Elementor\Plugin' ) ? \Elementor\Plugin::instance()->editor->is_edit_mode() : false,
				'is_bb_editor'         => class_exists( '\FLBuilderModel' ) ? \FLBuilderModel::is_builder_active() : false,
				'is_brizy_editor'      => class_exists( 'Brizy_Editor_Post' ) ? ( isset( $_GET['brizy-edit'] ) || isset( $_GET['brizy-edit-iframe'] ) ) : false, // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Fetching GET parameter, no nonce associated with this action.
				'saved_images'         => get_option( 'zipwp-images-saved-images', array() ),
				'title'                => apply_filters( 'zipwp_images_tab_title', __( 'Search Images', 'astra-sites' ) ),
				'search_placeholder'   => __( 'Search - Ex: flowers', 'astra-sites' ),
				'downloading'          => __( 'Downloading...', 'astra-sites' ),
				'validating'           => __( 'Validating...', 'astra-sites' ),
				'_ajax_nonce'          => wp_create_nonce( 'zipwp-images' ),
				'rest_api_nonce'       => current_user_can( 'edit_posts' ) ? wp_create_nonce( 'wp_rest' ) : '',
				'image_engines'        => self::get_images_engines(),
			)
		);

		// Add localize JS.
		wp_localize_script(
			'zipwp-images-script',
			'zipwpImages',
			$data
		);

		// Enqueue CSS.
		wp_enqueue_style( 'zipwp-images-style', ZIPWP_IMAGES_URL . 'dist/style-main.css', array(), ZIPWP_IMAGES_VER );
		wp_enqueue_style( 'zipwp-images-google-fonts', $this->google_fonts_url(), array(), 'all' );
	}

	/**
	 * Generate and return the Google fonts url.
	 *
	 * @since 1.0.0
	 * @return string
	 */
	public function google_fonts_url() {

		$fonts_url     = '';
		$font_families = array(
			'Figtree:400,500,600,700',
		);

		$query_args = array(
			'family' => rawurlencode( implode( '|', $font_families ) ),
			'subset' => rawurlencode( 'latin,latin-ext' ),
		);

		return add_query_arg( $query_args, '//fonts.googleapis.com/css' );
	}

	/**
	 * Get the server's country code using its public IP.
	 *
	 * @param string $provider Optional. GeoIP provider: 'ipwhois', 'ipapi', or 'ipinfo'. Default 'ipwhois'.
	 * @param string $token    Optional. API token (only needed for ipapi/ipinfo).
	 *
	 * @since 1.0.20
	 * @return string Two-letter ISO country code (e.g., 'RU', 'US'), or 'unknown' on failure.
	 */
	public static function get_server_country_code( $provider = 'ipwhois', $token = '' ) {
		// Step 1: Get server's public IP.
		$response = wp_safe_remote_get( 'https://api.ipify.org' );
		if ( is_wp_error( $response ) ) {
			return 'unknown';
		}

		$ip = wp_remote_retrieve_body( $response );
		if ( empty( $ip ) ) {
			return 'unknown';
		}

		// Step 2: Select provider endpoint.
		switch ( strtolower( $provider ) ) {
			case 'ipapi':
				// Requires token for higher limits.
				$url = "https://ipapi.co/{$ip}/country/";
				if ( ! empty( $token ) ) {
					$url = "https://ipapi.co/{$ip}/country/?key={$token}";
				}
				break;

			case 'ipinfo':
				$url = "https://ipinfo.io/{$ip}/country";
				if ( ! empty( $token ) ) {
					$url .= "?token={$token}";
				}
				break;

			case 'ipwhois':
			default:
				// Default: ipwho.is (no token needed).
				$url = "https://ipwho.is/{$ip}";
				break;
		}

		// Step 3: Make request.
		$response = wp_safe_remote_get( $url );
		if ( is_wp_error( $response ) ) {
			return 'unknown';
		}

		$body = wp_remote_retrieve_body( $response );

		// Step 4: Parse response based on provider.
		if ( 'ipwhois' === $provider ) {
			$data = json_decode( $body, true );
			if ( is_array( $data ) && isset( $data['country_code'] ) && is_string( $data['country_code'] ) ) {
				return $data['country_code'];
			}
			return 'unknown';
		}

		// ipapi and ipinfo return plain text country code.
		$country = trim( $body );
		return ! empty( $country ) ? $country : 'unknown';
	}

	/**
	 * Get Images Engines
	 *
	 * @since 1.0.20
	 * @return array<string> Image Engine.s
	 */
	public static function get_images_engines() {
		$country_code = get_transient( 'zipwp_images_server_country_code' );

		if ( false === $country_code ) {
			$country_code = self::get_server_country_code();
			set_transient( 'zipwp_images_server_country_code', $country_code, WEEK_IN_SECONDS );
		}

		// Use Unsplash for Russia as Pexels is blocked there.
		if ( 'RU' === $country_code ) {
			return [ 'unsplash' ];
		}

		// Default to Pexels.
		return [ 'pexels', 'pixabay' ];
	}
}

/**
 * Kicking this off by calling 'get_instance()' method
 */
Zipwp_Images_Script::get_instance();
