<?php
/**
 * Member Stats Service
 *
 * @package    Rewardswp
 * @subpackage Rewardswp/Services
 */

namespace Awesomemotive\Rewardswp\Services;

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

use Awesomemotive\Rewardswp\Models\Member;
use Awesomemotive\Rewardswp\Interfaces\IntegrationInterface;
use Exception;
use function Awesomemotive\Rewardswp\Helpers\get_human_readable_date;
use function Awesomemotive\Rewardswp\Helpers\get_site_currency_symbol;
use function Awesomemotive\Rewardswp\Helpers\format_currency;
use function Awesomemotive\Rewardswp\Helpers\get_member_points_earned;
use function Awesomemotive\Rewardswp\Helpers\get_member_points_spent;
use function Awesomemotive\Rewardswp\Helpers\get_member_points_redeemed;
use function Awesomemotive\Rewardswp\Helpers\get_member_pending_points;

/**
 * Class MemberStatsService
 *
 * @since 1.0.0
 */
class MemberStatsService {

	/**
	 * Integration instance.
	 *
	 * @since 1.0.0
	 * @var IntegrationInterface
	 */
	private IntegrationInterface $integration;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param IntegrationInterface $integration Integration instance.
	 */
	public function __construct( IntegrationInterface $integration ) {
		$this->integration = $integration;
	}

	/**
	 * Get all stats for a member.
	 *
	 * @since 1.0.0
	 *
	 * @param Member $member Member instance.
	 *
	 * @throws Exception
	 *
	 * @return array
	 */
	public function get_member_stats( Member $member ): array {
		return [
			'points'    => $this->get_points_stats( $member ),
			'referrals' => $this->get_referral_stats( $member ),
			'orders'    => $this->get_order_stats( $member ),
			'activity'  => $this->get_activity_stats( $member ),
		];
	}

	/**
	 * Get points statistics for a member.
	 *
	 * @since 1.0.0
	 *
	 * @param Member $member Member instance.
	 * @return array
	 */
	private function get_points_stats( Member $member ): array {
		return [
			'available' => $member->points_balance,
			'lifetime'  => get_member_points_earned( $member->id ),
			'spent'     => get_member_points_spent( $member->id ),
			'redeemed'  => get_member_points_redeemed( $member->id ),
			'pending'   => get_member_pending_points( $member->id ),
		];
	}

	/**
	 * Get referral statistics for a member.
	 *
	 * @param Member $member The member object.
	 *
	 * @return array An array containing completed, pending, total, revenue_display, and conversion_rate.
	 * @since 1.0.0
	 */
	public function get_referral_stats( Member $member ): array {
		$total_referrals     = $member->get_total_referral_count();
		$completed_referrals = $member->completed_referrals; // Assuming this property is correct for completed.
		$pending_referrals   = $member->get_pending_referral_count();
		$total_revenue       = $member->get_total_referral_revenue();

		// Calculate conversion rate based on completed / total (if total > 0).
		$conversion_rate = 0.0;
		if ( $total_referrals > 0 ) {
			$conversion_rate = round( ( $completed_referrals / $total_referrals ) * 100, 1 );
		}

		return [
			'completed'       => $completed_referrals,
			'pending'         => $pending_referrals,
			'total'           => $total_referrals,
			'revenue'         => $total_revenue,
			'revenue_display' => format_currency( $total_revenue ),
			'conversion_rate' => $conversion_rate . '%',
		];
	}

	/**
	 * Get order statistics for a member.
	 *
	 * @since 1.0.0
	 *
	 * @param Member $member Member instance.
	 *
	 * @throws Exception
	 *
	 * @return array
	 */
	public function get_order_stats( Member $member ): array {
		$orders = $this->integration->get_customer_orders( $member->email );

		$total_spend     = 0;
		$last_order_date = null;

		foreach ( $orders as $order ) {
			$total_spend += $order['total'];

			// Get the most recent order date
			if ( ! $last_order_date || strtotime( $order['date'] ) > strtotime( $last_order_date ) ) {
				$last_order_date = $order['date'];
			}
		}

		return [
			'orders'              => $orders,
			'total_spend'         => $total_spend,
			'total_spend_display' => format_currency( $total_spend ),
			'order_count'         => count( $orders ),
			'last_order_date'     => $last_order_date,
			'last_order_display'  => $last_order_date
				? get_human_readable_date( $last_order_date, true )
				: __( 'No orders', 'rewardswp' ),
		];
	}

	/**
	 * Get activity statistics for a member.
	 *
	 * @since 1.0.0
	 *
	 * @param Member $member Member instance.
	 *
	 * @throws Exception
	 *
	 * @return array
	 */
	private function get_activity_stats( Member $member ): array {
		$first_seen  = $member->created_at;
		$last_seen   = $member->get_meta( 'last_login_at' );
		$order_stats = $this->get_order_stats( $member );

		return [
			'first_seen'         => $first_seen,
			'first_seen_display' => empty( $first_seen )
				? esc_html__( 'N/A', 'rewardswp' )
				: get_human_readable_date( $first_seen, true ),
			'last_seen'          => $last_seen,
			'last_seen_display'  => empty( $last_seen )
				? esc_html__( 'Never', 'rewardswp' )
				: get_human_readable_date( $last_seen, true ),
			'last_order'         => $order_stats['last_order_date'],
			'last_order_display' => $order_stats['last_order_display'],
		];
	}
}
