<?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 ( is_null( self::$_instance ) ) {
            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;
	}
}
