<?php
/**
 * Column registration and rendering class.
 *
 * @package BW_Admin_Column
 */

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

class BW_Admin_Column_Columns {

	/**
	 * Singleton instance.
	 *
	 * @var BW_Admin_Column_Columns|null
	 */
	private static $instance = null;

	/**
	 * Cached settings array.
	 *
	 * @var array
	 */
	private $settings = array();

	/**
	 * Get singleton instance.
	 *
	 * @return BW_Admin_Column_Columns
	 */
	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor.
	 */
	private function __construct() {
		add_action( 'init', array( $this, 'bw_register_column_hooks' ), 99 );
		add_action( 'pre_get_posts', array( $this, 'bw_handle_column_sorting' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'bw_enqueue_list_assets' ) );
	}

	/**
	 * Register column hooks for each enabled post type.
	 * Runs at init priority 99 so all CPTs and taxonomies are registered.
	 */
	public function bw_register_column_hooks() {
		$this->settings = get_option( 'bw_admin_column_settings', array() );

		foreach ( $this->settings as $post_type => $pt_settings ) {
			if ( empty( $pt_settings['enabled'] ) ) {
				continue;
			}

			add_filter(
				"manage_{$post_type}_posts_columns",
				array( $this, 'bw_add_columns' )
			);

			add_action(
				"manage_{$post_type}_posts_custom_column",
				array( $this, 'bw_render_column' ),
				10,
				2
			);

			add_filter(
				"manage_edit-{$post_type}_sortable_columns",
				array( $this, 'bw_add_sortable_columns' )
			);
		}
	}

	/**
	 * Add custom columns to the post list table headers.
	 *
	 * @param array $columns Existing columns.
	 * @return array Modified columns.
	 */
	public function bw_add_columns( $columns ) {
		$screen = get_current_screen();
		if ( ! $screen ) {
			return $columns;
		}

		$post_type   = $screen->post_type;
		$pt_settings = isset( $this->settings[ $post_type ] ) ? $this->settings[ $post_type ] : array();

		// Featured Image column — insert before 'title'.
		if ( ! empty( $pt_settings['featured_image'] ) ) {
			$new_columns = array();
			foreach ( $columns as $key => $label ) {
				if ( 'title' === $key ) {
					$new_columns['bw_featured_image'] = __( 'Image', 'bw-admin-column' );
				}
				$new_columns[ $key ] = $label;
			}
			$columns = $new_columns;
		}

		// Taxonomy columns.
		if ( ! empty( $pt_settings['taxonomies'] ) ) {
			foreach ( $pt_settings['taxonomies'] as $taxonomy ) {
				$tax_obj = get_taxonomy( $taxonomy );
				if ( ! $tax_obj ) {
					continue;
				}
				// Skip if WordPress already added this taxonomy column.
				if ( isset( $columns[ 'taxonomy-' . $taxonomy ] ) ) {
					continue;
				}
				$columns[ 'bw_tax_' . $taxonomy ] = $tax_obj->labels->name;
			}
		}

		// Meta key columns.
		if ( ! empty( $pt_settings['meta_keys'] ) ) {
			foreach ( $pt_settings['meta_keys'] as $meta_key ) {
				$columns[ 'bw_meta_' . $meta_key ] = $this->bw_format_meta_key_label( $meta_key );
			}
		}

		return $columns;
	}

	/**
	 * Render content for custom columns.
	 *
	 * @param string $column_name Column identifier.
	 * @param int    $post_id     Current post ID.
	 */
	public function bw_render_column( $column_name, $post_id ) {

		// Featured image.
		if ( 'bw_featured_image' === $column_name ) {
			$this->bw_render_featured_image_column( $post_id );
			return;
		}

		// Taxonomy columns.
		if ( 0 === strpos( $column_name, 'bw_tax_' ) ) {
			$taxonomy = substr( $column_name, 7 );
			$this->bw_render_taxonomy_column( $post_id, $taxonomy );
			return;
		}

		// Meta key columns.
		if ( 0 === strpos( $column_name, 'bw_meta_' ) ) {
			$meta_key = substr( $column_name, 8 );
			$this->bw_render_meta_column( $post_id, $meta_key );
			return;
		}
	}

	/**
	 * Render the featured image cell for a post.
	 *
	 * @param int $post_id Post ID.
	 */
	private function bw_render_featured_image_column( $post_id ) {
		$thumbnail_id = get_post_thumbnail_id( $post_id );
		$nonce        = wp_create_nonce( 'bw_set_featured_image_' . $post_id );
		?>
		<div class="bw-featured-image-cell" data-post-id="<?php echo esc_attr( $post_id ); ?>" data-nonce="<?php echo esc_attr( $nonce ); ?>" title="<?php esc_attr_e( 'Click to change featured image', 'bw-admin-column' ); ?>">
			<?php if ( $thumbnail_id ) : ?>
				<?php echo get_the_post_thumbnail( $post_id, array( 50, 50 ), array( 'class' => 'bw-admin-thumb' ) ); ?>
			<?php else : ?>
				<span class="dashicons dashicons-format-image bw-no-thumb-icon"></span>
			<?php endif; ?>
		</div>
		<?php
	}

	/**
	 * Render a taxonomy column cell.
	 *
	 * @param int    $post_id  Post ID.
	 * @param string $taxonomy Taxonomy slug.
	 */
	private function bw_render_taxonomy_column( $post_id, $taxonomy ) {
		$terms = get_the_terms( $post_id, $taxonomy );

		if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
			$term_links = array();
			foreach ( $terms as $term ) {
				$link = add_query_arg(
					array(
						'post_type' => get_post_type( $post_id ),
						$taxonomy   => $term->slug,
					),
					admin_url( 'edit.php' )
				);
				$term_links[] = '<a href="' . esc_url( $link ) . '">' . esc_html( $term->name ) . '</a>';
			}
			echo implode( ', ', $term_links );
		} else {
			echo '<span aria-hidden="true">&#8212;</span>';
		}
	}

	/**
	 * Render a meta key column cell.
	 *
	 * @param int    $post_id  Post ID.
	 * @param string $meta_key Meta key name.
	 */
	private function bw_render_meta_column( $post_id, $meta_key ) {
		$value = get_post_meta( $post_id, $meta_key, true );

		if ( '' !== $value && null !== $value && false !== $value ) {
			$display = wp_strip_all_tags( is_array( $value ) ? wp_json_encode( $value ) : (string) $value );
			if ( strlen( $display ) > 80 ) {
				$display = substr( $display, 0, 77 ) . '...';
			}
			echo '<span title="' . esc_attr( $display ) . '">' . esc_html( $display ) . '</span>';
		} else {
			echo '<span aria-hidden="true">&#8212;</span>';
		}
	}

	/**
	 * Declare which custom columns are sortable.
	 *
	 * @param array $columns Existing sortable columns.
	 * @return array Modified sortable columns.
	 */
	public function bw_add_sortable_columns( $columns ) {
		$screen = get_current_screen();
		if ( ! $screen ) {
			return $columns;
		}

		$post_type   = $screen->post_type;
		$pt_settings = isset( $this->settings[ $post_type ] ) ? $this->settings[ $post_type ] : array();

		if ( empty( $pt_settings['meta_keys'] ) ) {
			return $columns;
		}

		foreach ( $pt_settings['meta_keys'] as $meta_key ) {
			$col_key             = 'bw_meta_' . $meta_key;
			$columns[ $col_key ] = $col_key;
		}

		return $columns;
	}

	/**
	 * Modify the main query when sorting by a custom meta column.
	 *
	 * @param WP_Query $query The main query.
	 */
	public function bw_handle_column_sorting( $query ) {
		if ( ! is_admin() || ! $query->is_main_query() ) {
			return;
		}

		$orderby = $query->get( 'orderby' );

		if ( 0 !== strpos( $orderby, 'bw_meta_' ) ) {
			return;
		}

		$meta_key = substr( $orderby, 8 );

		$query->set( 'meta_key', $meta_key );
		$query->set( 'orderby', 'meta_value' );

		// Include posts that don't have the meta key.
		$query->set( 'meta_query', array(
			'relation' => 'OR',
			array(
				'key'     => $meta_key,
				'compare' => 'EXISTS',
			),
			array(
				'key'     => $meta_key,
				'compare' => 'NOT EXISTS',
			),
		) );
	}

	/**
	 * Enqueue assets on post list screens where columns are enabled.
	 *
	 * @param string $hook Current admin page hook.
	 */
	public function bw_enqueue_list_assets( $hook ) {
		if ( 'edit.php' !== $hook ) {
			return;
		}

		$screen = get_current_screen();
		if ( ! $screen ) {
			return;
		}

		$post_type   = $screen->post_type;
		$pt_settings = isset( $this->settings[ $post_type ] ) ? $this->settings[ $post_type ] : array();

		if ( empty( $pt_settings['enabled'] ) ) {
			return;
		}

		wp_enqueue_style(
			'bw-admin-column-list',
			BW_ADMIN_COLUMN_URL . 'admin/css/bw-admin-column-list.css',
			array(),
			BW_ADMIN_COLUMN_VERSION
		);

		// Only load media uploader JS if featured image column is enabled.
		if ( ! empty( $pt_settings['featured_image'] ) ) {
			wp_enqueue_media();

			wp_enqueue_script(
				'bw-admin-column-list',
				BW_ADMIN_COLUMN_URL . 'admin/js/bw-admin-column-list.js',
				array( 'jquery' ),
				BW_ADMIN_COLUMN_VERSION,
				true
			);

			wp_localize_script( 'bw-admin-column-list', 'bwAdminColumnList', array(
				'ajaxUrl' => admin_url( 'admin-ajax.php' ),
				'i18n'    => array(
					'selectImage' => __( 'Select Featured Image', 'bw-admin-column' ),
					'useImage'    => __( 'Set as Featured Image', 'bw-admin-column' ),
				),
			) );
		}
	}

	/**
	 * Convert a meta key to a human-readable label.
	 *
	 * @param string $meta_key Meta key name.
	 * @return string Formatted label.
	 */
	private function bw_format_meta_key_label( $meta_key ) {
		$label = ltrim( $meta_key, '_' );
		$label = str_replace( array( '_', '-' ), ' ', $label );
		return ucwords( $label );
	}
}
