<?php
/*
 * Jetpack CRM
 * https://jetpackcrm.com
 *
 * WooSync: Contact Tabs
 *  Adds extra tabs to contact single view: vitals tab set
 */
namespace Automattic\JetpackCRM;

// block direct access
defined( 'ZEROBSCRM_PATH' ) || exit( 0 );

/**
 * WooSync Contact Tabs class
 */
class Woo_Sync_Contact_Tabs {

	/**
	 * The single instance of the class.
	 */
	protected static $_instance = null;

	/**
	 * Setup WooSync Contact Tabs
	 * Note: This will effectively fire after core settings and modules loaded
	 * ... effectively on tail end of `init`
	 */
	public function __construct() {

		// Initialise Hooks
		$this->init_hooks();
	}

	/**
	 * Main Class Instance.
	 *
	 * Ensures only one instance of Woo_Sync_Contact_Tabs is loaded or can be loaded.
	 *
	 * @since 2.0
	 * @static
	 * @see
	 * @return Woo_Sync_Contact_Tabs main instance
	 */
	public static function instance() {
		if ( self::$_instance === null ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	/**
	 * Initialise Hooks
	 */
	private function init_hooks() {

		// add in tabs
		add_filter( 'jetpack-crm-contact-vital-tabs', array( $this, 'append_info_tabs' ), 10, 2 );
	}

	/**
	 * Wire in ant applicable tabs (subs, memberships, bookings)
	 */
	public function append_info_tabs( $array, $id ) {

		if ( ! is_array( $array ) ) {
			$array = array();
		}

		// Woo Subscriptions
		if ( function_exists( 'wcs_get_users_subscriptions' ) ) {
			$array[] = array(
				'id'      => 'woocommerce-subscriptions-tab',
				'name'    => __( 'Subscriptions', 'zero-bs-crm' ),
				'content' => $this->generate_subscriptions_tab_html( $id ),
			);
		}

		// Woo Memberships
		if ( function_exists( 'wc_memberships_get_user_memberships' ) ) {
			$array[] = array(
				'id'      => 'woocommerce-memberships-tab',
				'name'    => __( 'Memberships', 'zero-bs-crm' ),
				'content' => $this->generate_memberships_tab_html( $id ),
			);
		}

		// Woo Bookings
		if ( class_exists( 'WC_Bookings_Controller' ) ) {
			$array[] = array(
				'id'      => 'woocommerce-bookings-tab',
				'name'    => __( 'Upcoming Bookings', 'zero-bs-crm' ),
				'content' => $this->generate_bookings_tab_html( $id ),
			);
		}

		return $array;
	}

	/**
	 * Draw the Woo Bookings Contact Vitals tab
	 */
	private function generate_bookings_tab_html( $object_id = -1 ) {

		global $zbs;

		// return html
		$html = '';

		// retrieve bookings
		$bookings = $zbs->modules->woosync->get_future_woo_bookings_for_object( $object_id );

		if ( count( $bookings ) > 0 ) {

			$html             .= '<div class="table-wrap woo-sync-book">';
				$html         .= '<table class="ui single line table">';
					$html     .= '<thead>';
					$html     .= '<tr>';
						$html .= '<th scope="col" class="booking-id">' . __( 'ID', 'woocommerce-bookings' ) . '</th>';
						$html .= '<th scope="col" class="booked-product">' . __( 'Booked', 'woocommerce-bookings' ) . '</th>';
						$html .= '<th scope="col" class="booking-start-date">' . __( 'Start Date', 'woocommerce-bookings' ) . '</th>';
						$html .= '<th scope="col" class="booking-end-date">' . __( 'End Date', 'woocommerce-bookings' ) . '</th>';
						$html .= '<th scope="col" class="booking-status">' . __( 'Status', 'woocommerce-bookings' ) . '</th>';
					$html     .= '</tr>';
				$html         .= '</thead>';
				$html         .= '<tbody>';
			foreach ( $bookings as $booking ) {

					$html     .= '<tr>';
						$html .= '<td class="booking-id">' . esc_html( $booking->get_id() ) . '</td>';
						$html .= '<td class="booked-product">';
				if ( $booking->get_product() && $booking->get_product()->is_type( 'booking' ) ) :
					$html .= '<a href="' . esc_url( get_permalink( $booking->get_product()->get_id() ) ) . '">';
					$html .= esc_html( $booking->get_product()->get_title() );
					$html .= '</a>';
							endif;
						$html .= '</td>';

						$status = esc_html( wc_bookings_get_status_label( $booking->get_status() ) );

						$html .= '<td class="booking-start-date">' . esc_html( $booking->get_start_date() ) . '</td>';
						$html .= '<td class="booking-end-date">' . esc_html( $booking->get_end_date() ) . '</td>';
						$html .= '<td><span class="ui label ' . strtolower( $status ) . '">' . $status . '</span></td>';

					$html .= '</tr>';
			}

					$html .= '</tbody>';
				$html     .= '</table>';
			$html         .= '</div>';

		} else {

			$html .= '<div class="ui message info blue"><i class="ui icon info circle"></i>' . __( 'This contact does not have any upcoming WooCommerce Bookings.', 'zero-bs-crm' ) . '</div>';

		}

		return $html;
	}

	/**
	 * Returns HTML that can be used to render the Subscriptions Table.
	 * When no WordPress user is found a <div> is returned with an info message.
	 * When no subscriptions are found a <div> is returned with an info message.
	 *
	 * @param integer $object_id Contact ID.
	 * @return string HTML that can be used to render the Subscriptions Table.
	 */
	private function generate_subscriptions_tab_html( $object_id = -1 ) {

		$subscriptions = array();
		if ( zeroBSCRM_getClientPortalUserID( $object_id ) > 0 ) {
			// Retrieve any subs against the main email or aliases.
			$subscriptions = $this->get_contact_subscriptions( $object_id );
		}
		if ( count( $subscriptions ) === 0 ) {
			return '<div class="ui message info blue"><i class="ui icon info circle"></i>' . __( 'This contact does not have any WooCommerce Subscriptions yet.', 'zero-bs-crm' ) . '</div>';
		}

		$html  = '';
		$html .= '<div class="table-wrap woo-sync-subs">';
		$html .= '<table class="ui single line table">';
		$html .= '<thead><tr>';
		$html .= '<th>' . __( 'Subscription', 'zero-bs-crm' ) . '</th>';
		$html .= '<th>' . __( 'Status', 'zero-bs-crm' ) . '</th>';
		$html .= '<th>' . __( 'Amount', 'zero-bs-crm' ) . '</th>';
		$html .= '<th>' . __( 'Start', 'zero-bs-crm' ) . '</th>';
		$html .= '<th>' . __( 'Renews', 'zero-bs-crm' ) . '</th>';
		$html .= '</tr></thead>';
		$html .= '<tbody>';

		foreach ( $subscriptions as $order_id ) {
			$order        = wc_get_order( $order_id );
			$status       = $order->get_status();
			$date_created = $order->get_date_created();
			$date_renew   = $order->get_date( 'next_payment_date' );
			$price        = $order->get_formatted_order_total();
			$name         = '';
			$sub_link     = admin_url( "post.php?post={$order_id}&action=edit" );
			$created      = jpcrm_uts_to_date_str( strtotime( $date_created ) );
			$next         = jpcrm_uts_to_date_str( strtotime( $date_renew ) );

			$html .= '<tr>';
			$html .= '<td><a href="' . esc_url( $sub_link ) . '">' . $name . __( ' Subscription #', 'zero-bs-crm' ) . $order_id . '</a></td>';
			$html .= '<td><span class="ui label ' . $status . '">' . $status . '</span></td>';
			$html .= '<td>' . $price . '</td>';
			$html .= '<td>' . $created . '</td>';
			$html .= '<td>' . $next . '</td>';
			$html .= '</tr>';

		}

		$html .= '</tbody>';
		$html .= '</table>';
		$html .= '</div>';

		return $html;
	}

	/**
	 * Generate HTML for memberships contact vitals tab
	 */
	private function generate_memberships_tab_html( $object_id = -1 ) {

		$data = $this->get_contact_memberships( $object_id );

		if ( $data['message'] === 'notfound' || count( $data['memberships'] ) <= 0 ) {

			return '<div class="ui message info blue"><i class="ui icon info circle"></i>' . __( 'This contact does not have any WooCommerce Memberships yet.', 'zero-bs-crm' ) . '</div>';

		}

		$memberships = $data['memberships'];

		$html  = '';
		$html .= '<div class="table-wrap woo-sync-mem">';
		$html .= '<table class="ui single line table">';
		$html .= '<thead><tr>';
		$html .= '<th>' . __( 'Membership', 'zero-bs-crm' ) . '</th>';
		$html .= '<th>' . __( 'Status', 'zero-bs-crm' ) . '</th>';
		$html .= '<th>' . __( 'Name', 'zero-bs-crm' ) . '</th>';
		$html .= '<th>' . __( 'Start', 'zero-bs-crm' ) . '</th>';
		$html .= '<th>' . __( 'Expires', 'zero-bs-crm' ) . '</th>';
		$html .= '</tr></thead>';
		$html .= '<tbody>';

		foreach ( $memberships as $membership ) {

			// populate fields
			$member_id    = $membership->id;
			$status       = $this->display_membership_status( $membership->get_status() );
			$name         = $membership->plan->name;
			$date_expires = $membership->get_end_date( 'Y-m-d H:i:s' );
			$date_created = $membership->get_start_date();
			$created      = jpcrm_uts_to_date_str( strtotime( $date_created ) );

			if ( empty( $date_expires ) ) {

				$expires = __( 'Never', 'zero-bs-crm' );

			} else {

				$expires = jpcrm_uts_to_date_str( strtotime( $date_expires ) );

			}

			$membership_link = admin_url( 'post.php?post=' . $membership->id . '&action=edit' );

			$html .= '<tr>';
			$html .= '<td><a href="' . esc_url( $membership_link ) . '">' . sprintf( __( ' Membership #%s', 'zero-bs-crm' ), $member_id ) . '</a></td>';
			$html .= '<td><span class="ui label ' . $status . '">' . $status . '</span></td>';
			$html .= '<td>' . $name . '</td>';
			$html .= '<td>' . $created . '</td>';
			$html .= '<td>' . $expires . '</td>';
			$html .= '</tr>';

		}

		$html .= '</tbody>';
		$html .= '</table>';
		$html .= '</div>';

		return $html;
	}

	/**
	 * Helper to display membership statuses
	 */
	private function display_membership_status( $status = '' ) {

		$woocommerce_statuses = array(
			'wcm-active'               => __( 'active', 'zero-bs-crm' ),
			'wcm-complimentary'        => __( 'complimentary', 'zero-bs-crm' ),
			'wcm-pending'              => __( 'pending', 'zero-bs-crm' ),
			'wcm-delayed'              => __( 'delayed', 'zero-bs-crm' ),
			'wcm-pending-cancelletion' => __( 'pending cancellation', 'zero-bs-crm' ),
			'wcm-paused'               => __( 'paused', 'zero-bs-crm' ),
			'wcm-expired'              => __( 'expired', 'zero-bs-crm' ),
			'wcm-cancelled'            => __( 'cancelled', 'zero-bs-crm' ),
		);

		$display_status = $status;

		if ( array_key_exists( $status, $woocommerce_statuses ) ) {

			$display_status = $woocommerce_statuses[ $status ];

		}

		return $display_status;
	}

	/**
	 * Retrieves memberships for a contact
	 */
	private function get_contact_memberships( $object_id = -1 ) {

		$wp_id = zeroBS_getCustomerWPID( $object_id );

		if ( $wp_id > 0 ) {

			return array(
				'message'     => 'success',
				'memberships' => wc_memberships_get_user_memberships( $wp_id ),
			);

		} else {

			return array(
				'message'     => 'notfound',
				'memberships' => array(),
			);

		}
	}

	/**
	 * Retrieves any Woo Subscriptions against a contact
	 *
	 * @param int $object_id Contact ID.
	 */
	private function get_contact_subscriptions( $object_id = -1 ) {
		$all_sub_statuses = array_keys( wcs_get_subscription_statuses() );

		$subscription_ids = array();

		if ( $object_id > 0 ) {

			// 1 - get the subscription IDs for the attached wp user
			$user_id = zeroBS_getCustomerWPID( $object_id );
			if ( $user_id > 0 ) {
				$args = array(
					'customer_id' => $user_id,
					'status'      => $all_sub_statuses,
					'type'        => 'shop_subscription',
					'return'      => 'ids',
				);

				$subscription_ids = wc_get_orders( $args );
			}

			// 2 - find subs for all emails (inc aliases)
			global $zbs;
			$emails = $zbs->DAL->contacts->getContactEmails( $object_id ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
			if ( is_array( $emails ) ) {

				foreach ( $emails as $email ) {
					if ( empty( $email ) ) {
						continue;
					}

					$args = array(
						'billing_email' => $email,
						'status'        => $all_sub_statuses,
						'type'          => 'shop_subscription',
						'return'        => 'ids',
					);

					$subscription_ids_by_email = wc_get_orders( $args );
					$subscription_ids          = array_merge( $subscription_ids, $subscription_ids_by_email );
				}
			}

			// 3 - remove any duplicate IDs between array_1 and array_2
			$subscription_ids = array_unique( $subscription_ids, SORT_REGULAR );
		}

		return $subscription_ids;
	}
}
