<?php
/**
 * SEO Bar
 *
 * Adds a custom "SEO" column to post/page/taxonomy list tables.
 * Runs real per-post assessments via SeoAssessment and renders
 * interactive tooltip blocks with per-check details.
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Admin;

use SEOvaultSEO\Core\PostMeta;
use SEOvaultSEO\Utils\SeoAssessment;
use SEOvaultSEO\Compatibility\Detector;

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

class SeoBar {

	private static $instance = null;

	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	private function __construct() {}

	public static function init() {
		if ( ! Detector::should_output_seo() ) {
			return;
		}

		add_action( 'admin_init', array( __CLASS__, 'setup_columns' ) );
		add_action( 'admin_init', array( __CLASS__, 'setup_taxonomy_columns' ) );
		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_assets' ) );
		add_action( 'load-edit.php', array( __CLASS__, 'prime_post_list_meta_cache' ) );
		add_action( 'load-edit-tags.php', array( __CLASS__, 'prime_term_list_meta_cache' ) );
	}

	/**
	 * Prefetch post meta for the current list-table page in one query.
	 *
	 * @return void
	 */
	public static function prime_post_list_meta_cache() {
		add_filter( 'the_posts', array( __CLASS__, 'filter_prime_postmeta_cache' ), 10, 2 );
	}

	/**
	 * Prime postmeta cache from the main list-table query results.
	 *
	 * @param array     $posts Posts.
	 * @param \WP_Query $query Query.
	 * @return array
	 */
	public static function filter_prime_postmeta_cache( $posts, $query ) {
		if ( empty( $posts ) || ! is_array( $posts ) || ! $query instanceof \WP_Query ) {
			return $posts;
		}

		$ids = array();
		foreach ( $posts as $post ) {
			if ( isset( $post->ID ) ) {
				$ids[] = (int) $post->ID;
			}
		}

		if ( ! empty( $ids ) ) {
			update_postmeta_cache( $ids );
		}

		return $posts;
	}

	/**
	 * Prefetch term meta for the current taxonomy list page.
	 *
	 * @return void
	 */
	public static function prime_term_list_meta_cache() {
		add_filter( 'get_terms', array( __CLASS__, 'filter_prime_termmeta_cache' ), 10, 2 );
	}

	/**
	 * Prime termmeta cache from taxonomy list query results.
	 *
	 * @param array|\WP_Error $terms      Terms.
	 * @param array           $taxonomies Taxonomies (unused).
	 * @return array|\WP_Error
	 */
	public static function filter_prime_termmeta_cache( $terms, $taxonomies = array() ) {
		if ( empty( $terms ) || is_wp_error( $terms ) || ! is_array( $terms ) ) {
			return $terms;
		}

		$ids = array();
		foreach ( $terms as $term ) {
			if ( is_object( $term ) && isset( $term->term_id ) ) {
				$ids[] = (int) $term->term_id;
			}
		}

		if ( ! empty( $ids ) && function_exists( 'update_termmeta_cache' ) ) {
			update_termmeta_cache( $ids );
		}

		return $terms;
	}

	public static function enqueue_assets( $hook ) {
		if ( ! in_array( $hook, array( 'edit.php', 'edit-tags.php', 'users.php' ), true ) ) {
			return;
		}

		wp_enqueue_style(
			'seovaultseo-seo-bar',
			SEOVAULT_SEO_URL . 'assets/css/seo-bar.css',
			array(),
			SEOVAULT_SEO_VERSION . '-2'
		);
	}

	public static function setup_columns() {
		$post_types = get_post_types( array( 'public' => true ), 'names' );
		$excluded   = apply_filters( 'seovaultseo_excluded_post_types', array( 'attachment' ) );

		foreach ( $post_types as $post_type ) {
			if ( in_array( $post_type, $excluded, true ) ) {
				continue;
			}
			add_filter( "manage_{$post_type}_posts_columns", array( __CLASS__, 'column_heading' ), 10, 1 );
			add_action( "manage_{$post_type}_posts_custom_column", array( __CLASS__, 'column_content' ), 10, 2 );
		}
	}

	public static function setup_taxonomy_columns() {
		$taxonomies = get_taxonomies( array( 'public' => true ), 'names' );
		$excluded   = apply_filters( 'seovaultseo_excluded_taxonomies', array() );

		foreach ( $taxonomies as $taxonomy ) {
			if ( in_array( $taxonomy, $excluded, true ) ) {
				continue;
			}
			add_filter( "manage_edit-{$taxonomy}_columns", array( __CLASS__, 'column_heading_taxonomy' ), 10, 1 );
			add_filter( "manage_{$taxonomy}_custom_column", array( __CLASS__, 'column_content_taxonomy' ), 10, 3 );
		}
	}

	public static function column_heading( $columns ) {
		$target_column = apply_filters( 'seovaultseo_seo_bar_column_position', 4 );
		$custom_column = array(
			'seovaultseo-data' => __( 'SEO', 'seovault-ai' ),
		);
		return array_slice( $columns, 0, $target_column, true ) + $custom_column + array_slice( $columns, $target_column, null, true );
	}

	public static function column_heading_taxonomy( $columns ) {
		$target_column = apply_filters( 'seovaultseo_seo_bar_column_position_taxonomy', 3 );
		$custom_column = array(
			'seovaultseo-data' => __( 'SEO', 'seovault-ai' ),
		);
		return array_slice( $columns, 0, $target_column, true ) + $custom_column + array_slice( $columns, $target_column, null, true );
	}

	public static function column_content( $column_name, $post_id ) {
		if ( 'seovaultseo-data' !== $column_name ) {
			return;
		}

		$result = SeoAssessment::assess_post( $post_id );
		echo wp_kses_post( self::render_badge( $result, $post_id ) );
	}

	public static function column_content_taxonomy( $content, $column_name, $term_id ) {
		if ( 'seovaultseo-data' !== $column_name ) {
			return $content;
		}

		$result = SeoAssessment::assess_term( $term_id );
		return wp_kses_post( self::render_badge( $result, $term_id ) );
	}

	/**
	 * Render the SEO badge with interactive tooltip containing per-check details.
	 *
	 * @param array $result Assessment result array (overall + checks).
	 * @param int   $id     Post or term ID.
	 * @return string
	 */
	private static function render_badge( $result, $id ) {
		$overall    = $result['overall'];
		$checks     = $result['checks'];
		$bar_status = SeoAssessment::to_bar_status( $overall );

		// Override to noindex badge if indexing check is bad due to noindex.
		foreach ( $checks as $check ) {
			if ( 'indexing' === $check['id'] && SeoAssessment::STATUS_BAD === $check['status'] ) {
				$bar_status = 'noindex';
				break;
			}
		}

		$labels = array(
			'good'    => __( 'Good', 'seovault-ai' ),
			'ok'      => __( 'Okay', 'seovault-ai' ),
			'warning' => __( 'Needs Work', 'seovault-ai' ),
			'empty'   => __( 'Not Set', 'seovault-ai' ),
			'noindex' => __( 'Noindex', 'seovault-ai' ),
		);

		$label = $labels[ $bar_status ] ?? $labels['empty'];

		// Build tooltip content from individual checks.
		$tooltip_items = '';
		foreach ( $checks as $check ) {
			$tooltip_items .= sprintf(
				'<li class="seovaultseo-tooltip-check seovaultseo-tooltip-check-%s"><span class="seovaultseo-tooltip-check-label">%s</span><span class="seovaultseo-tooltip-check-msg">%s</span></li>',
				esc_attr( $check['status'] ),
				esc_html( $check['label'] ),
				esc_html( $check['message'] )
			);
		}

		return sprintf(
			'<span class="seovaultseo-seo-bar-badge seovaultseo-seo-bar-%s" data-id="%d"><span class="seovaultseo-seo-bar-dot"></span>%s<span class="seovaultseo-seo-bar-tooltip"><ul>%s</ul></span></span>',
			esc_attr( $bar_status ),
			esc_attr( (string) $id ),
			esc_html( $label ),
			$tooltip_items
		);
	}
}
