<?php
/**
 * Upcoming Tours List Table.
 *
 * @since 1.3.8
 * @package tripzzy
 */

namespace Tripzzy\Admin;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

if ( ! class_exists( 'WP_List_Table' ) ) {
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

use Tripzzy\Core\Helpers\MetaHelpers;
use Tripzzy\Core\Bookings;
use Tripzzy\Core\Http\Nonce;
use Tripzzy\Core\Helpers\Amount;
use Tripzzy\Core\Helpers\Trip;

/**
 * UpcomingToursListTable Class.
 */
class UpcomingToursListTable extends \WP_List_Table {

	/**
	 * Current View Mode.
	 *
	 * @var string
	 */
	public $view_mode = 'summary';

	/**
	 * Selected Trip Date.
	 *
	 * @var string
	 */
	public $selected_date = '';

	/**
	 * Total Booking Count.
	 *
	 * @var int
	 */
	public $total_booking_count = 0;

	/**
	 * Constructor.
	 */
	public function __construct() {
		parent::__construct(
			array(
				'singular' => __( 'Upcoming Tour', 'tripzzy' ),
				'plural'   => __( 'Upcoming Tours', 'tripzzy' ),
				'ajax'     => false,
			)
		);

		if ( Nonce::verify() && isset( $_GET['tour_date'] ) && ! empty( $_GET['tour_date'] ) ) { // phpcs:ignore
			$this->view_mode     = 'detail';
			$this->selected_date = sanitize_text_field( $_GET['tour_date'] ); // phpcs:ignore
		}
	}

	/**
	 * Prepare items.
	 */
	public function prepare_items() {
		// Check search first to set view mode.
		$search_term = '';
		if ( isset( $_REQUEST['s'] ) && ! empty( $_REQUEST['s'] ) ) { // phpcs:ignore
			$this->view_mode = 'detail';
			$search_term     = sanitize_text_field( $_REQUEST['s'] ); // phpcs:ignore
		}

		$columns  = $this->get_columns();
		$hidden   = array();
		$sortable = $this->get_sortable_columns();

		$this->_column_headers = array( $columns, $hidden, $sortable );

		$per_page     = 20;
		$current_page = $this->get_pagenum();
		$total_items  = 0;

		$args = array(
			'post_type'      => 'tripzzy_booking',
			'post_status'    => 'publish',
			'posts_per_page' => -1, // Fetch all to filter/sort in PHP.
			'meta_query'     => array(), // phpcs:ignore
		);

		$query             = new \WP_Query( $args );
		$all_bookings      = $query->posts;
		$upcoming_bookings = array();

		$today  = date( 'Y-m-d' ); // phpcs:ignore
		$filter = isset( $_GET['filter'] ) ? sanitize_text_field( $_GET['filter'] ) : 'all'; // phpcs:ignore

		foreach ( $all_bookings as $booking ) {
			$booking_id    = $booking->ID;
			$cart_contents = MetaHelpers::get_post_meta( $booking_id, 'cart_contents' );
			if ( ! empty( $cart_contents ) && is_array( $cart_contents ) ) {
				$first_item = reset( $cart_contents );
				if ( isset( $first_item['start_date'] ) ) {
					$start_date = $first_item['start_date'];
					if ( $start_date >= $today ) {

						// Apply Filter.
						$include = true;
						if ( 'today' === $filter ) {
							if ( $start_date !== $today ) {
								$include = false;
							}
						} elseif ( 'this-week' === $filter ) {
							$end_of_week = date( 'Y-m-d', strtotime( 'sunday this week' ) ); // phpcs:ignore
							if ( $start_date > $end_of_week ) {
								$include = false;
							}
						} elseif ( 'this-month' === $filter ) {
							$end_of_month = date( 'Y-m-t' ); // phpcs:ignore
							if ( $start_date > $end_of_month ) {
								$include = false;
							}
						}

						if ( ! $include ) {
							continue;
						}

						$trip_name = $first_item['title'] ?? '';

						// Filter by search term if present.
						if ( $search_term ) {
							$checkout_info = MetaHelpers::get_post_meta( $booking_id, 'checkout_info' );
							$first_name    = $checkout_info['billing_first_name'] ?? '';
							$last_name     = $checkout_info['billing_last_name'] ?? '';
							$customer_name = trim( "$first_name $last_name" );
							$email         = $checkout_info['billing_email'] ?? '';

							$found = false;
							if ( stripos( (string) $booking_id, $search_term ) !== false ) {
								$found = true;
							}
							if ( stripos( $customer_name, $search_term ) !== false ) {
								$found = true;
							}
							if ( stripos( $trip_name, $search_term ) !== false ) {
								$found = true;
							}
							if ( stripos( $email, $search_term ) !== false ) {
								$found = true;
							}

							if ( ! $found ) {
								continue;
							}
						}

						$booking->trip_start_date = $start_date;
						$booking->trip_name       = $trip_name;
						$booking->trip_id         = $first_item['trip_id'];
						$upcoming_bookings[]      = $booking;
					}
				}
			}
		}

		// Sort by trip_start_date.
		usort(
			$upcoming_bookings,
			function ( $a, $b ) {
				return strcmp( $a->trip_start_date, $b->trip_start_date );
			}
		);

		$this->total_booking_count = count( $upcoming_bookings );

		if ( 'summary' === $this->view_mode ) {
			// Group by date.
			$grouped_bookings = array();
			foreach ( $upcoming_bookings as $booking ) {
				$date = $booking->trip_start_date;
				if ( ! isset( $grouped_bookings[ $date ] ) ) {
					$grouped_bookings[ $date ] = array(
						'date'      => $date,
						'count'     => 0,
						'travelers' => 0,
						'bookings'  => array(),
					);
				}
				$grouped_bookings[ $date ]['count']++; // phpcs:ignore
				$grouped_bookings[ $date ]['bookings'][] = $booking;

				// Calculate Travelers.
				$booking_id    = $booking->ID;
				$cart_contents = MetaHelpers::get_post_meta( $booking_id, 'cart_contents' );
				$travelers     = 0;
				if ( ! empty( $cart_contents ) && is_array( $cart_contents ) ) {
					$first_item = reset( $cart_contents );
					if ( isset( $first_item['categories'] ) ) {
						foreach ( $first_item['categories'] as $cat_qty ) {
							$travelers += (int) $cat_qty;
						}
					}
				}
				$grouped_bookings[ $date ]['travelers'] += $travelers;
			}
			$this->items = array_values( $grouped_bookings );
			$total_items = count( $this->items );

			// Pagination for summary view.
			$this->items = array_slice( $this->items, ( ( $current_page - 1 ) * $per_page ), $per_page );

		} else {
			// Detail view.
			if ( ! empty( $this->selected_date ) ) {
				// Filter by selected date.
				$filtered_bookings = array();
				foreach ( $upcoming_bookings as $booking ) {
					if ( $booking->trip_start_date === $this->selected_date ) {
						$filtered_bookings[] = $booking;
					}
				}
				$this->items = $filtered_bookings;
			} else {
				// Show all (e.g. search results).
				$this->items = $upcoming_bookings;
			}

			$total_items = count( $this->items );

			// Pagination for detail view.
			$this->items = array_slice( $this->items, ( ( $current_page - 1 ) * $per_page ), $per_page );
		}

		$this->set_pagination_args(
			array(
				'total_items' => $total_items,
				'per_page'    => $per_page,
				'total_pages' => ceil( $total_items / $per_page ),
			)
		);
	}

	/**
	 * Get columns.
	 *
	 * @return array
	 */
	public function get_columns() {
		if ( 'summary' === $this->view_mode ) {
			return array(
				'tour_date'  => __( 'Tour Date', 'tripzzy' ),
				'count'      => __( 'Upcoming Tours', 'tripzzy' ),
				'travelers' => __( 'No of Travelers', 'tripzzy' ),
			);
		} else {
			return array(
				// 'cb'         => '<input type="checkbox" />',
				'tour_date'  => __( 'Tour Date', 'tripzzy' ),
				'booking_id' => __( 'Booking ID', 'tripzzy' ),
				'trip_name'  => __( 'Tour Name', 'tripzzy' ),
				'customer'   => __( 'Customer', 'tripzzy' ),
				'status'     => __( 'Status', 'tripzzy' ),
			);
		}
	}

	/**
	 * Column default.
	 *
	 * @param object|array $item        Item.
	 * @param string       $column_name Column name.
	 * @return string
	 */
	public function column_default( $item, $column_name ) {
		if ( 'summary' === $this->view_mode ) {
			switch ( $column_name ) {
				case 'tour_date':
					$date_obj = new \DateTime( $item['date'] );
					$content  = '<span class="tripzzy-upcoming-tours-date">';
					$content .= sprintf( '<span class="tripzzy-upcoming-tours-month">%s</span>', esc_html( $date_obj->format( 'M' ) ) );
					$content .= sprintf( '<span class="tripzzy-upcoming-tours-day">%s</span>', esc_html( $date_obj->format( 'd' ) ) );
					$content .= '</span>';
					return $content;
				case 'travelers':
					$travelers_text = sprintf(
						/* translators: 1: No. of travelers. */
						_n( '%s traveler', '%s travelers', $item['travelers'], 'tripzzy' ),
						number_format_i18n( $item['travelers'] )
					);
					return sprintf( '<span class="tripzzy-travelers-count"><span class="dashicons dashicons-groups"></span> %s</span>', esc_html( $travelers_text ) );
				case 'count':
					$url = add_query_arg(
						array(
							'page'          => 'tripzzy-upcoming-tours',
							'tour_date'     => $item['date'],
							'tripzzy_nonce' => Nonce::create(),
						),
						admin_url( 'edit.php?post_type=tripzzy_booking' )
					);

					// Generate Tooltip Content.
					$tooltip_content  = '<div class="tripzzy-tooltip-table-wrapper" style="width:100%;">';
					$tooltip_content .= '<div class="tripzzy-tooltip-header" style="display:flex; font-weight:bold; border-bottom:1px solid #ccc; padding-bottom:5px; margin-bottom:5px;">';
					$tooltip_content .= sprintf( '<div style="flex:0 0 50px; margin-right:10px;">%s</div>', __( 'ID', 'tripzzy' ) );
					$tooltip_content .= sprintf( '<div style="flex:1; margin-right:10px;">%s</div>', __( 'Traveler Name', 'tripzzy' ) );
					$tooltip_content .= sprintf( '<div style="flex:1; margin-right:10px;">%s</div>', __( 'Trip', 'tripzzy' ) );
					$tooltip_content .= sprintf( '<div style="flex:0 0 80px; margin-right:10px;">%s</div>', __( 'Duration', 'tripzzy' ) );
					$tooltip_content .= sprintf( '<div style="flex:0 0 80px; margin-right:10px;">%s</div>', __( 'Cost', 'tripzzy' ) );
					$tooltip_content .= sprintf( '<div style="flex:0 0 80px; margin-right:10px;">%s</div>', __( 'Travelers', 'tripzzy' ) );
					$tooltip_content .= sprintf( '<div style="flex:0 0 80px;">%s</div>', __( 'Status', 'tripzzy' ) );
					$tooltip_content .= '</div>';
					$tooltip_content .= '<div class="tripzzy-tooltip-body">';

					foreach ( $item['bookings'] as $booking ) {
						$booking_id     = $booking->ID;
						$checkout_info  = MetaHelpers::get_post_meta( $booking_id, 'checkout_info' );
						$first_name     = $checkout_info['billing_first_name'] ?? '';
						$last_name      = $checkout_info['billing_last_name'] ?? '';
						$customer_name  = trim( "$first_name $last_name" );
						$trip_name      = $booking->trip_name;
						$trip_id        = $booking->trip_id;
						$booking_status = Bookings::get_booking_status( $booking_id );

						// Calculate No of travelers.
						$cart_contents = MetaHelpers::get_post_meta( $booking_id, 'cart_contents' );
						$travelers    = 0;
						if ( ! empty( $cart_contents ) && is_array( $cart_contents ) ) {
							$first_item = reset( $cart_contents );
							if ( isset( $first_item['categories'] ) ) {
								foreach ( $first_item['categories'] as $cat_qty ) {
									$travelers += (int) $cat_qty;
								}
							}
						}

						// Duration.
						$trip         = new Trip( $trip_id );
						$duration     = $trip->get_duration( null, false );
						$duration_str = sprintf( '%s %s', esc_html( $duration['duration'][0] ), esc_html( $duration['duration_unit'][0] ) );

						// Cost.
						$booking_total  = Bookings::get_total( $booking_id );
						$formatted_cost = Amount::display( $booking_total );

						$tooltip_content .= '<div class="tripzzy-tooltip-row" style="display:flex; border-bottom:1px solid #eee; padding:5px 0;">';
						$tooltip_content .= sprintf( '<div style="flex:0 0 50px; margin-right:10px;">#%d</div>', esc_html( $booking_id ) );
						$tooltip_content .= sprintf( '<div style="flex:1; margin-right:10px;">%s</div>', esc_html( $customer_name ) );
						$tooltip_content .= sprintf( '<div style="flex:1; margin-right:10px;">#%d %s</div>', esc_html( $trip_id ), esc_html( $trip_name ) );
						$tooltip_content .= sprintf( '<div style="flex:0 0 80px; margin-right:10px;">%s</div>', esc_html( $duration_str ) );
						$tooltip_content .= sprintf( '<div style="flex:0 0 80px; margin-right:10px;">%s</div>', esc_html( $formatted_cost ) );
						$tooltip_content .= sprintf( '<div style="flex:0 0 80px; margin-right:10px;">%d</div>', $travelers );
						$tooltip_content .= sprintf( '<div style="flex:0 0 80px;">%s</div>', esc_html( $booking_status ) );
						$tooltip_content .= '</div>';
					}
					$tooltip_content .= '</div></div>';

					$count_text = sprintf(
						/* translators: 1: No. of bookings for the day. */
						_n( '%s tour', '%s tours', $item['count'], 'tripzzy' ),
						number_format_i18n( $item['count'] )
					);
					$count_html = sprintf( '<a class="tripzzy-tours-count-link" href="%s"><span class="dashicons dashicons-calendar-alt"></span> %s</a>', esc_url( $url ), $count_text );

					// Tooltip Markup.
					$tooltip_html = sprintf(
						'<div class="tripzzy-tooltip-container" style="display:inline-block; margin-left:5px;">
							<div class="tripzzy-tooltip-icon">
								<span class="dashicons dashicons-info" style="font-size:16px; width:16px; height:16px;"></span>
							</div>
							<div class="tripzzy-tooltip" style="min-width: 800px; width: auto; white-space: normal;">%s</div>
						</div>',
						$tooltip_content
					);

					return '<div class="tripzzy-upcoming-tours-count">' . $count_html . $tooltip_html . '</div>';
				default:
					return print_r( $item, true ); // phpcs:ignore
			}
		} else {
			// Detail view.
			switch ( $column_name ) {
				case 'booking_id':
					$edit_link = get_edit_post_link( $item->ID );
					return sprintf( '<a href="%s">#%d</a>', esc_url( $edit_link ), $item->ID );
				case 'trip_name':
					return esc_html( $item->trip_name );
				case 'tour_date':
					$date_obj = new \DateTime( $item->trip_start_date );
					$content  = '<span class="tripzzy-upcoming-tours-date">';
					$content .= sprintf( '<span class="tripzzy-upcoming-tours-month">%s</span>', esc_html( $date_obj->format( 'M' ) ) );
					$content .= sprintf( '<span class="tripzzy-upcoming-tours-day">%s</span>', esc_html( $date_obj->format( 'd' ) ) );
					$content .= '</span>';
					return $content;
				case 'customer':
					$checkout_info = MetaHelpers::get_post_meta( $item->ID, 'checkout_info' );
					$first_name    = $checkout_info['billing_first_name'] ?? '';
					$last_name     = $checkout_info['billing_last_name'] ?? '';
					$email         = $checkout_info['billing_email'] ?? '';
					return sprintf( '%s %s<br><a href="mailto:%s">%s</a>', esc_html( $first_name ), esc_html( $last_name ), esc_attr( $email ), esc_html( $email ) );
				case 'status':
					return Bookings::get_booking_status( $item->ID );
				default:
					return print_r( $item, true ); // phpcs:ignore
			}
		}
	}

	/**
	 * Column cb.
	 *
	 * @param object $item Item.
	 * @return string
	 */
	public function column_cb( $item ) {
		if ( 'summary' === $this->view_mode ) {
			return '';
		}
		return sprintf(
			'<input type="checkbox" name="booking[]" value="%s" />',
			$item->ID
		);
	}

	/**
	 * Print column headers.
	 *
	 * @param bool $with_id Whether to set the id attribute or not.
	 */
	// public function print_column_headers( $with_id = true ) {
	// 	if ( 'summary' === $this->view_mode && ! $with_id ) {
	// 		$total_text = sprintf(
	// 			/* translators: 1: No. of bookings for the day. */
	// 			_n( '%s tour', '%s tours', $this->total_booking_count, 'tripzzy' ),
	// 			number_format_i18n( $this->total_booking_count )
	// 		);
	// 		echo '<tr>';
	// 		echo '<th>' . esc_html__( 'Total', 'tripzzy' ) . '</th>';
	// 		echo '<th colspan="2">' . esc_html( $total_text ) . '</th>';
	// 		echo '</tr>';
	// 	} else {
	// 		parent::print_column_headers( $with_id );
	// 	}
	// }
}
