<?php
/**
 * Theme Onboarding Sites_Listing
 *
 * @package    templates-patterns-collection
 */

namespace TIOB;

/**
 * Class Sites_Listing
 */
class Sites_Listing {

	/**
	 * Sites Listing API URL
	 */
	const API = 'https://api.themeisle.com/sites/wp-json/demosites-api/sites';

	/**
	 * Key of transient where we save the sites list.
	 *
	 * The key is version-stamped so that a plugin update always busts a
	 * potentially stuck cache.
	 *
	 * @var string
	 */
	private $transient_key = 'tiob_sites_' . TIOB_VERSION;

	/**
	 * How long the sites list cache is considered fresh, in seconds.
	 *
	 * @var int
	 */
	private $cache_ttl = 12 * HOUR_IN_SECONDS;

	/**
	 * The onboarding config.
	 *
	 * @var array
	 */
	private $onboarding_config = array();

	/**
	 * Initialize the Class.
	 */
	public function init() {
		// Personalization is applied on the client via /starter_order.
		$this->onboarding_config = array(
			'remote'      => $this->get_sites(),
			'upsell'      => array(),
			'can_migrate' => array(
				'zerif-pro'  => array(
					'theme_name'        => 'Zelle Pro',
					'theme_mod_check'   => 'zelle_frontpage_was_imported',
					'template'          => 'zelle',
					'heading'           => __( 'Want to keep using Zelle\'s homepage?', 'templates-patterns-collection' ),
					'description'       => __( 'Hi! We\'ve noticed you were using Zelle before. To make your transition easier, we can help you keep the same beautiful homepage you had before, by converting it into an Elementor template. This option will also import your homepage content.', 'templates-patterns-collection' ),
					'mandatory_plugins' => array(
						'elementor' => 'Elementor Page Builder',
					),
				),
				'zerif-lite' => array(
					'theme_name'        => 'Zelle Lite',
					'theme_mod_check'   => 'zelle_frontpage_was_imported',
					'template'          => 'zelle',
					'heading'           => __( 'Want to keep using Zelle\'s homepage?', 'templates-patterns-collection' ),
					'description'       => __( 'Hi! We\'ve noticed you were using Zelle before. To make your transition easier, we can help you keep the same beautiful homepage you had before, by converting it into an Elementor template. This option will also import your homepage content.', 'templates-patterns-collection' ),
					'mandatory_plugins' => array(
						'elementor' => 'Elementor Page Builder',
					),
				),
			),
			'pro_link'    => tsdk_translate_link( tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'onboarding' ), 'query' ),
		);
		$this->add_sites_library_support();
	}

	/**
	 * Return the API path
	 *
	 * @return string
	 */
	final public static function get_api_path() {
		if ( defined( 'TPC_USE_STAGING' ) && TPC_USE_STAGING === true ) {
			return ( ( defined( 'TPC_API_STAGING' ) && ! empty( TPC_API_STAGING ) ) ? TPC_API_STAGING : self::API ) . self::add_query_args();
		}
		return self::API . self::add_query_args();
	}

	/**
	 * Allows adding $_GET arguments to API path.
	 *
	 * @return string
	 */
	private static function add_query_args() {
		$query_args   = array();
		$allowed_keys = array(
			'show-legacy-sites',
		);
		// filter all keys that are not in $allowed_keys since the filter can provide third parties access to the URL.
		$query_args   = array_intersect_key( apply_filters( 'tpc_starter_api_query_filter', $query_args ), array_flip( $allowed_keys ) );
		$query_string = http_build_query( $query_args );

		return ( ! empty( $query_string ) ) ? '?' . $query_string : '';
	}

	/**
	 * Add theme support
	 */
	public function add_sites_library_support() {
		add_theme_support( 'themeisle-demo-import', $this->get_ti_demo_content_support_data() );
	}

	/**
	 * Get the sites
	 *
	 * @return array
	 */
	private function get_sites() {
		$response  = $this->get_cached_sites();
		$is_cached = ( $response !== false );

		if ( ! $is_cached ) {
			$response = wp_remote_get( esc_url( self::get_api_path() ) );

			if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
				return array();
			}

			$response = wp_remote_retrieve_body( $response );

			$response = json_decode( $response, true );

			if ( ! is_array( $response ) || empty( $response ) ) {
				return array();
			}
		}

		require_once ABSPATH . 'wp-admin/includes/plugin.php';
		$upsell_status = $this->get_upsell_status();

		$divi  = array(
			array(
				'name'       => 'Divi Builder',
				'active'     => is_plugin_active( 'divi-builder/divi-builder.php' ),
				'author_url' => esc_url( 'https://www.elegantthemes.com/gallery/divi/' ),
			),
		);
		$thive = array(
			array(
				'name'       => 'Thrive Architect',
				'active'     => is_plugin_active( 'thrive-visual-editor/thrive-visual-editor.php' ),
				'author_url' => esc_url( 'https://thrivethemes.com/architect/' ),
			),
		);

		foreach ( $response as $editor => $sites ) {
			foreach ( $sites as $slug => $site_data ) {
				if ( $editor === 'divi builder' ) {
					$response[ $editor ][ $slug ]['external_plugins'] = $divi;
				}
				if ( $editor === 'thrive architect' ) {
					$response[ $editor ][ $slug ]['external_plugins'] = $thive;
				}
				if ( isset( $site_data['upsell'] ) ) {
					$response[ $editor ][ $slug ]['upsell'] = $upsell_status;
				}
			}
		}

		if ( ! $is_cached ) {
			set_transient(
				$this->transient_key,
				array(
					'fetched_at' => time(),
					'data'       => $response,
				),
				$this->cache_ttl
			);
		}

		return $response;
	}

	/**
	 * Get the cached sites list, if it is still fresh.
	 *
	 * Instead of relying solely on the transient timeout row - which external
	 * DB/transient cleanup tools can strip, leaving the value non-expiring and
	 * served forever - we embed our own `fetched_at` timestamp in the payload
	 * and validate it on read.
	 *
	 * @return array|false The cached sites data, or false when there is no
	 *                     fresh cache and a fresh fetch is required.
	 */
	private function get_cached_sites() {
		$cache = get_transient( $this->transient_key );

		if ( ! is_array( $cache ) || ! isset( $cache['fetched_at'], $cache['data'] ) ) {
			return false;
		}

		if ( ( time() - (int) $cache['fetched_at'] ) >= $this->cache_ttl ) {
			return false;
		}

		return $cache['data'];
	}

	/**
	 * Get the themeisle demo content support data.
	 *
	 * @return array
	 */
	private function get_ti_demo_content_support_data() {
		$this->reorder_starter_sites();
		return apply_filters( 'neve_filter_onboarding_sites', $this->onboarding_config );
	}

	/**
	 * Reorder starter sites based on previous theme
	 *
	 * @return bool
	 */
	private function reorder_starter_sites() {
		$previous_theme = get_theme_mod( 'ti_prev_theme' );
		if ( empty( $previous_theme ) ) {
			return false;
		}

		$slug_association = array(
			'zerif-pro'      => 'neve-zelle',
			'zerif-lite'     => 'neve-zelle',
			'themotion'      => 'neve-themotion',
			'themotion-lite' => 'neve-themotion',
			'amadeus'        => 'neve-amadeus',
			'rokophoto-lite' => 'neve-rokophoto',
			'rokophoto'      => 'neve-rokophoto',
			'oblique'        => 'neve-oblique',
			'shop-isle'      => 'neve-shop',
			'shop-isle-pro'  => 'neve-shop',
			'lawyeria-lite'  => 'neve-lawyer',
			'lawyeria'       => 'neve-lawyer',
		);
		if ( ! array_key_exists( $previous_theme, $slug_association ) ) {
			return false;
		}
		if ( ! isset( $this->onboarding_config['local']['elementor'][ $slug_association[ $previous_theme ] ] ) ) {
			return false;
		}
		$starter_site = $this->onboarding_config['local']['elementor'][ $slug_association[ $previous_theme ] ];
		unset( $this->onboarding_config['local']['elementor'][ $slug_association[ $previous_theme ] ] );
		$this->onboarding_config['local']['elementor'] = array( $slug_association[ $previous_theme ] => $starter_site ) + $this->onboarding_config['local']['elementor'];

		return true;
	}

	/**
	 * Get upsell status.
	 *
	 * @return bool
	 */
	private function get_upsell_status() {
		$category         = apply_filters( 'product_neve_license_plan', -1 );
		$category_mapping = array(
			1 => 1,
			2 => 1,
			3 => 2,
			4 => 2,
			5 => 3,
			6 => 3,
			7 => 1,
			8 => 2,
			9 => 3,
		);
		return apply_filters( 'product_neve_license_status', false ) !== 'valid' || ! isset( $category_mapping[ $category ] ) || $category_mapping[ $category ] < 2;
	}
}
