<?php
/**
 * Fundraiser List Table Columns
 *
 * @package AmbassadorHub\Fundraisers\Admin
 */

namespace AmbassadorHub\Fundraisers\Admin;

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

use AmbassadorHub\Admin\DateTimeHelper;
use AmbassadorHub\Admin\StatsListTableActions;
use AmbassadorHub\Donations\DonationsModule;
use AmbassadorHub\Fundraisers\Admin\Settings\SettingsManager;
use AmbassadorHub\Fundraisers\FundraisersHelpers;
use AmbassadorHub\Fundraisers\FundraisersModule;

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter

/**
 * Manages custom columns on the fundraiser list table (edit.php).
 */
final class ListTable {

	/**
	 * Initialize list table hooks.
	 *
	 * @return void
	 */
	public static function init(): void {
		add_filter( 'manage_' . FundraisersModule::POST_TYPE . '_posts_columns', array( self::class, 'add_custom_columns' ) );
		add_action( 'manage_' . FundraisersModule::POST_TYPE . '_posts_custom_column', array( self::class, 'render_custom_columns' ), 10, 2 );

		StatsListTableActions::init(
			FundraisersModule::POST_TYPE,
			FundraisersModule::STATS_PAGE_SLUG,
			'page_row_actions'
		);

		add_action( 'restrict_manage_posts', array( self::class, 'render_root_filter' ) );
		add_action( 'pre_get_posts', array( self::class, 'apply_root_filter' ) );

		add_filter( 'post_class', array( self::class, 'add_team_row_class' ), 10, 3 );
		add_filter( 'display_post_states', array( self::class, 'add_pending_verification_state' ), 10, 2 );
	}

	/**
	 * Add custom columns to the fundraiser list table.
	 *
	 * @param array $columns Existing columns.
	 * @return array Modified columns.
	 */
	public static function add_custom_columns( array $columns ): array {
		$new_columns = array();
		foreach ( $columns as $key => $value ) {
			$new_columns[ $key ] = $value;
			if ( 'title' === $key ) {
				$new_columns['root_fundraiser'] = __( 'Root Fundraiser', 'ambassadorhub' );
				$new_columns['owner']           = __( 'Owner', 'ambassadorhub' );
				$new_columns['target']          = __( 'Target', 'ambassadorhub' );
				$new_columns['donations_total'] = __( 'Raised', 'ambassadorhub' );
				$new_columns['end_date']        = __( 'End Date', 'ambassadorhub' );
			}
		}
		return $new_columns;
	}

	/**
	 * Render custom column content.
	 *
	 * @param string $column  Column name.
	 * @param int    $post_id Post ID.
	 * @return void
	 */
	public static function render_custom_columns( string $column, int $post_id ): void {
		switch ( $column ) {
			case 'root_fundraiser':
				$post = get_post( $post_id );
				if ( $post && 0 === (int) $post->post_parent ) {
					// This IS the root fundraiser.
					echo '<em>' . esc_html__( '(root)', 'ambassadorhub' ) . '</em>';
					break;
				}
				$root_id = FundraisersHelpers::get_root_fundraiser_id( $post_id );
				if ( $root_id > 0 ) {
					$stats_url = add_query_arg(
						array(
							'page'    => FundraisersModule::STATS_PAGE_SLUG,
							'post_id' => $root_id,
						),
						admin_url( 'admin.php' )
					);
					echo '<a href="' . esc_url( $stats_url ) . '">' . esc_html( get_the_title( $root_id ) ) . '</a>';
				} else {
					echo '—';
				}
				break;

			case 'owner':
				$user_id = (int) get_post_field( 'post_author', $post_id );
				if ( $user_id ) {
					$user = get_user_by( 'ID', $user_id );
					if ( $user ) {
						echo '<a href="' . esc_url( get_edit_user_link( $user_id ) ) . '">' . esc_html( $user->display_name ) . '</a>';
					} else {
						echo '—';
					}
				} else {
					echo '—';
				}
				break;

			case 'target':
				$target = get_post_meta( $post_id, '_ambh_target_amount', true );
				if ( $target ) {
					echo esc_html( SettingsManager::format_currency( (float) $target ) );
				} else {
					echo '—';
				}
				break;

			case 'donations_total':
				global $wpdb;
				$table_name = DonationsModule::get_table_name();
				$total      = $wpdb->get_var(
					$wpdb->prepare(
						"SELECT COALESCE(SUM(amount), 0) FROM $table_name WHERE fundraiser_id = %d AND status = 'completed'",
						$post_id
					)
				);
				echo esc_html( SettingsManager::format_currency( (float) $total ) );
				break;

			case 'end_date':
				$end_date_gmt = FundraisersHelpers::get_effective_end_date_gmt( $post_id );
				if ( $end_date_gmt ) {
					$local = DateTimeHelper::convert_gmt_to_local( $end_date_gmt );
					echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $local ) ) );
				} else {
					echo '—';
				}
				break;
		}
	}

	/**
	 * Render a root-fundraiser filter dropdown above the list table.
	 *
	 * @param string $post_type Current post type.
	 * @return void
	 */
	public static function render_root_filter( string $post_type ): void {
		if ( FundraisersModule::POST_TYPE !== $post_type ) {
			return;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$selected = isset( $_GET['ambh_root_filter'] ) ? absint( $_GET['ambh_root_filter'] ) : 0;

		$root_ids = get_posts(
			array(
				'post_type'      => FundraisersModule::POST_TYPE,
				'post_status'    => 'any',
				'posts_per_page' => -1,
				'orderby'        => 'title',
				'order'          => 'ASC',
				'fields'         => 'ids',
				'post_parent'    => 0,
			)
		);

		echo '<select name="ambh_root_filter" id="ambh_root_filter">';
		echo '<option value="">' . esc_html__( 'All root fundraisers', 'ambassadorhub' ) . '</option>';

		foreach ( $root_ids as $root_id ) {
			$root_id = (int) $root_id;
			echo '<option value="' . esc_attr( (string) $root_id ) . '"' . selected( $selected, $root_id, false ) . '>'
				. esc_html( get_the_title( $root_id ) )
				. '</option>';
		}

		echo '</select>';
	}

	/**
	 * Apply the root fundraiser filter to the main admin query.
	 *
	 * Limits the list to fundraisers that are either the selected root or
	 * any of its descendants.
	 *
	 * @param \WP_Query $query The current WP_Query instance.
	 * @return void
	 */
	public static function apply_root_filter( \WP_Query $query ): void {
		global $pagenow;

		if ( ! is_admin() || ! $query->is_main_query() ) {
			return;
		}

		if ( 'edit.php' !== $pagenow || FundraisersModule::POST_TYPE !== $query->get( 'post_type' ) ) {
			return;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$root_id = isset( $_GET['ambh_root_filter'] ) ? absint( $_GET['ambh_root_filter'] ) : 0;

		if ( ! $root_id ) {
			return;
		}

		$all_ids   = self::get_all_descendant_ids( $root_id );
		$all_ids[] = $root_id;

		$query->set( 'post__in', $all_ids );
	}

	/**
	 * Add an 'ambh-is-team' CSS class to team fundraiser rows in the admin list table.
	 *
	 * @param string[] $classes Array of post CSS classes.
	 * @param string[] $class   Array of additional classes.
	 * @param int      $post_id The post ID.
	 * @return string[] Modified classes.
	 */
	public static function add_team_row_class( array $classes, array $_class, int $post_id ): array {
		if ( get_post_meta( $post_id, '_ambh_is_team', true ) === '1' ) {
			$classes[] = 'ambh-is-team';
		}
		return $classes;
	}

	/**
	 * Append a post state badge to fundraiser titles in the list table.
	 *
	 * @param string[]  $post_states Existing post state labels.
	 * @param \WP_Post  $post        Current post object.
	 * @return string[] Modified post states.
	 */
	public static function add_pending_verification_state( array $post_states, \WP_Post $post ): array {
		if ( FundraisersModule::POST_TYPE !== $post->post_type ) {
			return $post_states;
		}
		if ( 'pending_verification' === $post->post_status ) {
			$post_states['pending_verification'] = __( 'Pending Verification', 'ambassadorhub' );
		}
		if ( 'ended' === $post->post_status ) {
			$post_states['ended'] = __( 'Ended', 'ambassadorhub' );
		}
		return $post_states;
	}

	/**
	 * Recursively collect all descendant fundraiser IDs under a given parent.
	 *
	 * @param int $parent_id Root/parent fundraiser post ID.
	 *
	 * @return int[]
	 */
	private static function get_all_descendant_ids( int $parent_id ): array {
		$ids      = array();
		$children = get_posts(
			array(
				'post_type'      => FundraisersModule::POST_TYPE,
				'post_parent'    => $parent_id,
				'posts_per_page' => -1,
				'fields'         => 'ids',
				'post_status'    => 'any',
			)
		);

		foreach ( $children as $child_id ) {
			$ids[] = (int) $child_id;
			$ids   = array_merge( $ids, self::get_all_descendant_ids( (int) $child_id ) );
		}

		return $ids;
	}
}
