<?php
/**
 * Landing
 *
 * @package StrategyBlocks
 */

namespace StrategyBlocks;

use StrategySuite\Analytics\GA4_Automation;

/**
 * Landing Module
 *
 * Handles Landing Page functionality within the StrategyBlocks system.
 * Includes admin-only features such as analytics meta boxes,
 * custom fields, and integration with third-party plugins.
 */
class Landing extends \StrategyBlocks\Module {

	/**
	 * Google Analytics property identifier.
	 *
	 * @var string
	 */
	private $ga_property = '';

	/**
	 * Only register if on an admin page and if fieldmanager plugin is active.
	 *
	 * @return bool
	 */
	public function can_register() {
		return true;
	}

	/**
	 * Register our hooks.
	 *
	 * @return void
	 */
	public function register() {
		add_action( 'init', [ $this, 'register_post_type' ] );
		// Leaving out of release because of errors.
		// add_action( 'add_meta_boxes', [ $this, 'add_landing_page_analytics_meta_box' ] );
		// add_action( 'wp_ajax_refresh_landing_page_analytics', [ $this, 'ajax_refresh_data' ] );
		add_action( 'pre_get_posts', [ $this, 'exclude_landing_pages_from_search' ] );
		add_filter( 'wpseo_robots', [ $this, 'disable_yoast_indexing' ] );
	}

	/**
	 * Register landing-page cpt.
	 *
	 * @return void
	 */
	public function register_post_type() {
		$labels = array(
			'name'                  => __( 'Landing Pages', 'lead-gen' ),
			'singular_name'         => __( 'Landing Page', 'lead-gen' ),
			'menu_name'             => __( 'Landing Pages', 'lead-gen' ),
			'name_admin_bar'        => __( 'Landing Pages', 'lead-gen' ),
			'add_new'               => __( 'Add Landing Page', 'lead-gen' ),
			'add_new_item'          => __( 'Add New Landing Page', 'lead-gen' ),
			'new_item'              => __( 'New Landing Page', 'lead-gen' ),
			'edit_item'             => __( 'Edit Landing Page', 'lead-gen' ),
			'view_item'             => __( 'View Landing Page', 'lead-gen' ),
			'all_items'             => __( 'All Landing Pages', 'lead-gen' ),
			'search_items'          => __( 'Search Landing Pages', 'lead-gen' ),
			'not_found'             => __( 'No Landing Pages found.', 'lead-gen' ),
			'not_found_in_trash'    => __( 'No Landing Pages found.', 'lead-gen' ),
		);

		$args = array(
			'labels'                => $labels,
			'public'                => true,
			'exclude_from_search'   => true,
			'publicly_queryable'    => true,
			'show_ui'               => true,
			'show_in_menu'          => true,
			'menu_icon'             => 'dashicons-welcome-add-page',
			'query_var'             => true,
			'rewrite'               => array(
				'slug' => 'lp',
				'with_front' => false,
			),
			'capability_type'       => 'post',
			'has_archive'           => false,
			'hierarchical'          => false,
			'supports'              => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
			'show_in_rest'          => true,
		);

		register_post_type( 'landing-page', $args );
	}

	/**
	 * Exclude Landing Pages and Yoast noindex posts from front-end search.
	 *
	 * Removes the 'landing-page' post type from public search results and
	 * filters out any posts marked as noindex in Yoast SEO settings, while
	 * keeping normal post and page visibility unchanged.
	 *
	 * @param WP_Query $query The current WordPress query instance.
	 *
	 * @return void
	 */
	public function exclude_landing_pages_from_search( $query ) {
		if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
			$post_types = (array) $query->get( 'post_type' );
			if ( empty( $post_types ) ) {
				$post_types = [ 'post', 'page' ];
			}
			$query->set( 'post_type', array_diff( $post_types, [ 'landing-page' ] ) );

			$meta_query = (array) $query->get( 'meta_query', [] );
			$meta_query[] = array(
				'relation' => 'OR',
				array(
					'key'     => '_yoast_wpseo_meta-robots-noindex',
					'compare' => 'NOT EXISTS',
				),
				array(
					'key'     => '_yoast_wpseo_meta-robots-noindex',
					'value'   => '1',
					'compare' => '!=',
				),
			);
			$query->set( 'meta_query', $meta_query );
		}
	}

	/**
	 * Disable Yoast indexing for specific post types.
	 *
	 * @param array $robots Current robots directives.
	 *
	 * @return array Modified robots directives.
	 */
	public function disable_yoast_indexing( $robots ) {
		global $post;
		if ( isset( $post ) && 'landing-page' === $post->post_type ) {
			$robots = 'noindex, nofollow, max-snippet:-1, max-image-preview:large, max-video-preview:-1';
		}
		return $robots;
	}

	/**
	 * Add the Landing Page Analytics meta box.
	 *
	 * Registers a sidebar meta box displaying performance data
	 * for 'landing-page' post types when editing an existing post.
	 *
	 * @return void
	 */
	public function add_landing_page_analytics_meta_box() {
		$screen = get_current_screen();

		if ( $screen && 'landing-page' === $screen->post_type && isset( $_GET['post'] ) ) {
			add_meta_box(
				'landing-page-analytics',
				__( 'Analytics', 'lead-gen' ),
				[ $this, 'render_analytics_metabox' ],
				'landing-page',
				'side',
				'high'
			);
		}
	}

	/**
	 * Renders a custom meta box for Landing Page analytics.
	 *
	 * Displays performance data from Google Analytics 4 and Google Ads for
	 * the Landing Page post type, along with a "Refresh Data" button.
	 *
	 * @param WP_Post $post The current post object.
	 * @return void
	 */
	public function render_analytics_metabox( $post ) {
		if ( empty( $post->ID ) ) {
			return;
		}

		$analytics_options = get_field( 'analytics_automation', 'options' );
		$this->ga_property = $analytics_options['ga4_measurement_id'];

		$data = $this->get_cached_analytics_data( $post->ID );
		$last_updated = $this->get_last_updated_time( $post->ID );

		echo '<div class="components-flex components-v-stack">';
		$this->render_last_updated_row( $last_updated );
		$this->render_ga4_row( $data['ga4'] ?? [] );
		$this->render_google_ads_row( $data['ads'] ?? [] );
		$this->render_refresh_button( $post->ID );
		echo '</div>';

		$this->render_refresh_script();
	}

	/**
	 * Retrieve cached analytics data for a landing page.
	 *
	 * Attempts to load analytics data from a transient cache.
	 * If no cached data is found, it fetches fresh analytics data
	 * and stores it in the transient for 30 minutes.
	 *
	 * @param int $post_id The landing page post ID.
	 * @return mixed The analytics data array or object.
	 */
	private function get_cached_analytics_data( $post_id ) {
		$data = get_transient( 'landing_page_analytics_' . $post_id );
		if ( ! $data ) {
			$data = $this->get_analytics_data( $post_id );
			set_transient( 'landing_page_analytics_' . $post_id, $data, 30 * MINUTE_IN_SECONDS );
		}
		return $data;
	}

	/**
	 * Get the last updated timestamp for a landing page's analytics data.
	 *
	 * Checks the post meta key '_analytics_last_updated'. If not set,
	 * returns the current time in MySQL format.
	 *
	 * @param int $post_id The landing page post ID.
	 * @return string Last updated timestamp in 'Y-m-d H:i:s' format.
	 */
	private function get_last_updated_time( $post_id ) {
		$last_updated = get_post_meta( $post_id, '_analytics_last_updated', true );
		return $last_updated ? $last_updated : current_time( 'mysql' );
	}

	/**
	 * Render the "Last Updated" row in the landing page analytics meta box.
	 *
	 * @param string $last_updated Timestamp of the last analytics update.
	 */
	private function render_last_updated_row( $last_updated ) {
		?>
		<div class="components-flex components-h-stack editor-post-panel__row">
			<div class="editor-post-content-information">
				<span data-wp-component="Text" class="components-truncate components-text">
					<strong><?php esc_html_e( 'Last Updated:', 'lead-gen' ); ?></strong>
					<?php echo esc_html( gmdate( 'M j, Y, g:i A', strtotime( $last_updated ) ) ); ?>
				</span>
			</div>
		</div>
		<?php
	}

	/**
	 * Render the Google Analytics (GA4) row in the landing page analytics meta box.
	 *
	 * @param array $ga4 GA4 data array containing views, engagement, conversion rate, and top source.
	 */
	private function render_ga4_row( $ga4 ) {
		?>
		<div class="components-flex components-h-stack editor-post-panel__row">
			<div class="editor-post-panel__row-label" style="width:100%;"><strong><?php esc_html_e( 'Google Analytics', 'lead-gen' ); ?></strong></div>
			<div class="editor-post-panel__row-control">
				<?php if ( ! $this->ga_property ) : ?>
					<p style="margin:0; color:#d63638;">
						<?php esc_html_e( 'To get analytics data, please insert a GA4 Measurement ID in your Site Settings and click "Refresh data".', 'lead-gen' ); ?>
					</p>
				<?php elseif ( ! empty( $ga4 ) ) : ?>
					<ul style="margin:0; padding-left:18px;">
						<li>Views (7d): <?php echo esc_html( $ga4['views'] ); ?></li>
						<li>Avg Engagement: <?php echo esc_html( $ga4['engagement'] ); ?></li>
						<li>Conversion Rate: <?php echo esc_html( $ga4['conversion_rate'] ); ?>%</li>
						<li>Top Source: <?php echo esc_html( $ga4['top_source'] ); ?></li>
					</ul>
				<?php endif; ?>
			</div>
		</div>
		<?php
	}

	/**
	 * Render the Google Ads row in the landing page analytics meta box.
	 *
	 * @param array $ads Google Ads data array containing clicks, impressions, CTR, avg CPC, and conversions.
	 */
	private function render_google_ads_row( $ads ) {
		$ads_credentials = $this->get_google_ads_credentials();
		?>
		<div class="components-flex components-h-stack editor-post-panel__row">
			<div class="editor-post-panel__row-label" style="width:100%;">
				<strong><?php esc_html_e( 'Google Ads', 'lead-gen' ); ?></strong>
			</div>
			<div class="editor-post-panel__row-control">
				<?php if ( empty( $ads_credentials ) ) : ?>
					<p style="margin:0; color:#d63638;">
						<?php esc_html_e( 'To get Google Ads data, please define your credentials (GOOGLE_ADS_DEVELOPER_TOKEN, GOOGLE_ADS_MANAGER_ID, GOOGLE_ADS_CUSTOMER_ID) in your config and click "Refresh data".', 'lead-gen' ); ?>
					</p>
				<?php elseif ( ! empty( $ads ) ) : ?>
					<ul style="margin:0; padding-left:18px;">
						<li>Clicks: <?php echo esc_html( $ads['clicks'] ); ?></li>
						<li>Impressions: <?php echo esc_html( $ads['impressions'] ); ?></li>
						<li>CTR: <?php echo esc_html( $ads['ctr'] ); ?>%</li>
						<li>Avg CPC: $<?php echo esc_html( $ads['avg_cpc'] ); ?></li>
						<li>Conversions: <?php echo esc_html( $ads['conversions'] ); ?></li>
					</ul>
				<?php endif; ?>
			</div>
		</div>
		<?php
	}

	/**
	 * Render the "Refresh Data" button in the landing page analytics meta box.
	 *
	 * @param int $post_id The current post ID.
	 */
	private function render_refresh_button( $post_id ) {
		?>
		<div class="components-flex components-h-stack editor-post-panel__row">
			<div class="editor-post-panel__row-control">
				<button type="button" class="components-button is-primary js-refresh-analytics" data-post="<?php echo esc_attr( $post_id ); ?>" style="margin-top:10px;">
					<?php esc_html_e( 'Refresh Data', 'lead-gen' ); ?>
				</button>
			</div>
		</div>
		<?php
	}

	/**
	 * Render the JavaScript for the "Refresh Data" button in the landing page analytics meta box.
	 * Handles the AJAX request and reloads the page when complete.
	 */
	private function render_refresh_script() {
		?>
		<script>
			document.addEventListener('DOMContentLoaded', () => {
				const btn = document.querySelector('.js-refresh-analytics');
				if (!btn) return;
				btn.addEventListener('click', () => {
					btn.disabled = true;
					btn.textContent = 'Refreshing...';
					fetch(ajaxurl + '?action=refresh_landing_page_analytics&post_id=' + btn.dataset.post)
						.then(r => r.json())
						.then(() => location.reload());
				});
			});
		</script>
		<?php
	}

	/**
	 * Get Google Ads credentials if all are defined.
	 *
	 * @return array Array containing developer_token, manager_id, customer_id, or empty array if missing.
	 */
	private function get_google_ads_credentials() {
		$dev_token   = defined( 'GOOGLE_ADS_DEVELOPER_TOKEN' ) ? GOOGLE_ADS_DEVELOPER_TOKEN : '';
		$manager_id  = defined( 'GOOGLE_ADS_MANAGER_ID' ) ? GOOGLE_ADS_MANAGER_ID : '';
		$customer_id = defined( 'GOOGLE_ADS_CUSTOMER_ID' ) ? GOOGLE_ADS_CUSTOMER_ID : '';

		if ( empty( $dev_token ) || empty( $manager_id ) || empty( $customer_id ) ) {
			return [];
		}

		return [
			'developer_token' => $dev_token,
			'manager_id'      => $manager_id,
			'customer_id'     => $customer_id,
		];
	}

	/**
	 * Fetch analytics data for a landing page, including GA4 and Google Ads.
	 *
	 * @param int $post_id The ID of the landing page post.
	 *
	 * @return array Analytics data with 'ga4' and 'ads' keys.
	 */
	private function get_analytics_data( $post_id ) {
		$url       = get_permalink( $post_id );
		$post_slug = get_post_field( 'post_name', $post_id );
		$short_url = '/lp/' . $post_slug . '/';

		$ga4_data  = [];
		$ads_data  = [];

		if ( $this->ga_property ) {
			$ga4 = new GA4_Automation( $this->ga_property, $url );
		}

		if ( isset( $ga4 ) ) {
			try {
				$report = $ga4->get_report_data( $short_url );
				if ( $report ) {
					$ga4_data = $report;
				}
			} catch ( \Google\ApiCore\ApiException $e ) {
				error_log( 'GA4 API error: ' . $e->getMessage() );
			}
		}

		$ads_credentials = $this->get_google_ads_credentials();
		if ( ! empty( $ads_credentials ) && isset( $ga4 ) ) {
			try {
				$ads_data = $ga4->get_ads_data(
					$ads_credentials['developer_token'],
					$ads_credentials['manager_id'],
					$ads_credentials['customer_id']
				);
			} catch ( \Google\ApiCore\ApiException $e ) {
				error_log( 'Google Ads API error: ' . $e->getMessage() );
			}
		}

		update_post_meta( $post_id, '_analytics_last_updated', current_time( 'mysql' ) );

		return [
			'ga4' => $ga4_data,
			'ads' => $ads_data,
		];
	}

	/**
	 * AJAX handler to refresh landing page analytics.
	 * Deletes the cached transient so data will be re-fetched on next load.
	 */
	public function ajax_refresh_data() {
		$post_id = intval( $_GET['post_id'] ?? 0 );
		delete_transient( 'landing_page_analytics_' . $post_id );
		wp_send_json_success();
	}
}
