<?php

namespace CarDealerPress\includes\helpers;

use CarDealerPress\Includes\Database\Requests;

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

/**
 * This is the primary class for the SEO Helpers.
 *
 * It uses standard WordPress hooks and helpers for the different APIs it interfaces with.
 *
 * @package    WordPress
 * @subpackage Plugin
 */
class Dynamic_Site_Headers {

	/**
	 * Public variable for the host of the API we are supposed to request the headers from.
	 *
	 * @access public
	 * @var string
	 */
	public $host = null;

	/**
	 * Public variable for the company ID we'll be giving to the API.
	 *
	 * @access public
	 * @var integer
	 */
	public $company_id = 0;

	/**
	 * Public array of the parameters we'll be submitting to the API.
	 *
	 * @access public
	 * @var array
	 */
	public $parameters = array();

	/**
	 * Public array of the headers returned form the API.
	 *
	 * @access public
	 * @var array
	 */
	public $headers = array();

	/**
	 * Public array all requests made within the instance of the object.
	 *
	 * @access public
	 * @var array
	 */
	public $request_stack = array();

	/**
	 * Public variable for the host of the API we are suposed to request the headers from.
	 *
	 * @access public
	 * @var string
	 */
	public $discourage_seo = null;

	private $company;

	/**
	 * Sets up object properties and ties into the WordPress procedural hooks. PHP 5 style constructor.
	 *
	 * @return void
	 */
	public function __construct( $company_id ) {
		$this->host           = BASE_INVENTORY_API_URL;
		$this->company_id     = $company_id;
		add_filter( 'wpseo_robots', '__return_empty_array' ); // Removes Yoast output.
		add_filter('wp_robots', array(&$this, 'remove_robots')); // Disable core output.
		add_filter( 'rank_math/frontend/robots', '__return_empty_array'); // Removes Math Rank output.
		$this->discourage_seo = Option::check_for_option(
			'cdp_admin_options',
			array(
				'admin',
				'general',
				'discourage_seo_visibility',
			)
		);
		$this->company        = ( new Requests() )->cdp_company_dealer_request( $company_id )[0] ?? array();
	}

	public function remove_robots() {
		return array();
	}


	/**
	 * Set the new title we get from the API.
	 *
	 * @return string The new title from the API.
	 * @since 3.0.0
	 */
	public function set_title() {
		if ( $this->seo_check() ) {
			return $this->headers['page_title'] . ' ';
		}
	}

	/**
	 * Check for SEO company subscription
	 **/
	public function seo_check(): bool {
		return ! empty( $this->company['seo'] );
	}

	/**
	 * Set the header information for the site we got back from the VMS.
	 *
	 * @return void
	 * @since 3.0.0
	 */
	public function set_head_information() {
		if ( isset( $this->headers['ogimage'] ) ) {
			echo '<meta property="og:image" content="' . esc_url( $this->headers['ogimage'] ) . '" />' . "\n";
		}
		if ( isset( $this->headers['page_description'] ) && ! empty( $this->headers['page_description'] ) ) {
			echo '<meta name="Description" content="' . esc_attr( $this->headers['page_description'] ) . '" />' . "\n";
		}
		if ( isset( $this->headers['page_keywords'] ) && ! empty( $this->headers['page_keywords'] ) ) {
			echo '<meta name="Keywords" content="' . esc_attr( $this->headers['page_keywords'] ) . '" />' . "\n";
		}
		if ( empty( $this->discourage_seo ) ) {
			$meta_follow_or_index = ( $this->shouldFollowOrIndex( 'follow' ) ? "follow" : "nofollow" ) . ", ";
			$meta_follow_or_index .= $this->shouldFollowOrIndex( 'index' ) ? "index" : "noindex";
		} else {
			$meta_follow_or_index = 'nofollow, noindex';
		}
		echo '<meta name="robots" content="' . esc_attr( $meta_follow_or_index ) .', max-image-preview:large, max-snippet:-1, max-video-preview:-1" />';
	}

	private function shouldFollowOrIndex(string $key): bool
	{
		return isset($this->headers[$key]) && $this->headers[$key];
	}

	public function apply_headers( $parameters ) {
		$seo = $this->set_seo();
		foreach ( $seo as $key => $value ) {
			if ( ! empty( $value ) ) {
				$parameters[ $key ] = $value;
			}
		}
		$this->parameters = $parameters;
		$this->get_headers();
		if ( ! empty( $this->headers ) ) {
			add_filter( 'wp_title', array( &$this, 'set_title' ) );
			add_filter( 'pre_get_document_title', array( &$this, 'set_title' ), 20 );
			add_action( 'wp_head', array( &$this, 'set_head_information' ), 1 );
		}
	}

	public function set_seo() {
		if ( $this->seo_check() ) {
			return array(
				'city'         => $this->company['city'],
				'state'        => $this->company['state'],
				'country_code' => $this->company['country_code'],
			);
		} else {
			return array(
				'city'         => '',
				'state'        => '',
				'country_code' => '',
			);
		}
	}

	/**
	 * Attempt to get the title and meta information from the VMS.
	 *
	 * @return void
	 * @since 3.0.0
	 */
	public function get_headers() {

		$taxonomy = $this->parameters['taxonomy'] ?? 'inventory';
		unset( $this->parameters['taxonomy'] );
		$sale_class = $this->parameters['saleclass'] ?? 'All';
		unset( $this->parameters['saleclass'] );
		$year = $this->parameters['year'] ?? false;
		unset( $this->parameters['year'] );
		$make = isset( $this->parameters['make'] ) ? rawurlencode( $this->parameters['make'] ) : 'All';
		unset( $this->parameters['make'] );
		$model = isset( $this->parameters['model'] ) ? rawurlencode( $this->parameters['model'] ) : 'All';
		unset( $this->parameters['model'] );
		$trim = isset( $this->parameters['trim'] ) ? rawurlencode( $this->parameters['trim'] ) : 'All';
		unset( $this->parameters['trim'] );
		$city = isset( $this->parameters['city'] ) ? rawurlencode( $this->parameters['city'] ) : false;
		unset( $this->parameters['city'] );
		$state = isset( $this->parameters['state'] ) ? rawurlencode( $this->parameters['state'] ) : false;
		unset( $this->parameters['state'] );
		$vin = $this->parameters['vin'] ?? false;
		unset( $this->parameters['vin'] );

		// Remove Extras.
		unset( $this->parameters['per_page'] );

		// GEO Override.
		// @codingStandardsIgnoreStart
		$safe = helpers::sanitize_get($_GET );
		// @codingStandardsIgnoreEnd

		$city  = $safe['geo_city'] ?? $city;
		$state = $safe['geo_state'] ?? $state;

		$base = false !== $year ? $year : $sale_class;
		if ( false === $year ) {
			$url = urldecode( $this->host ) . '/' . $this->company_id . '/seo_helpers.json?cu=/' . $taxonomy . '/' . $base . '/All/' . $make . '/' . $model . '/' . $city . '/' . $state . '/';
		} else {
			$url = urldecode( $this->host ) . '/' . $this->company_id . '/seo_helpers.json?cu=/' . $taxonomy . '/' . $base . '/' . $make . '/' . $model . '/' . $vin . '/' . $city . '/' . $state . '/';
			$this->set_fb_headers( $vin );
		}
		if ( 'all' !== strtolower( $trim ) ) {
			$url .= '?trim=' . rawurldecode( $trim );
		}
		$url .= '?' . http_build_query( $this->parameters, '', '&' );
		if ( $this->seo_check() ) {
			$request_handler       = new Http_Request( $url, 'dynamic_site_headers' );
			$this->request_stack['url'] = $url;
			$response              = $request_handler->get_file( true );
			$body                  = ! empty( $response['body'] ) ? json_decode( $response['body'] ) : array();
		} else {
			$body = false;
		}
		if ( $body ) {
			$this->headers['page_title']       = isset( $body->page_title ) ? rawurldecode( $body->page_title ) : '';
			$this->headers['page_description'] = $body->page_description ?? '';
			$this->headers['page_keywords']    = $body->page_keywords ?? '';
			$this->headers['follow']           = $body->follow ?? '';
			$this->headers['index']            = $body->index ?? '';
		} else {
			$headers = false;
		}
	}

	public function set_fb_headers( $vin ) {
		$vehicle_url = urldecode( $this->host ) . '/' . $this->company_id . '/inventory/vehicles.json?vin=' . $vin;
		// TODO: future, use db for image rather than calling api
		// Blocker: update image in db to be large first.
		// Check for no_image photo
		//$db_vehicle = ($vin ? (new Requests())->cdp_db_init('inventory', $vin)[0] : array());
		//$this->headers['ogimage'] = $db_vehicle['thumbnail'];
		if ( isset( $vehicle_url ) ) {
			$response_vehicle = wp_remote_request( $vehicle_url );
			$response_body    = wp_remote_retrieve_body( $response_vehicle );
			$response_code    = wp_remote_retrieve_response_code( $response_vehicle );
			if ( ( 200 === $response_code ) && isset( $response_body ) ) {
				$vehicle                  = json_decode( $response_body );
				$photo_large              = $vehicle->photos ? rawurldecode( $vehicle->photos[0]->large ) : '';
				$this->headers['ogimage'] = $photo_large ?? '';
			}
		}
	}

}
