<?php
/**
 * Base Segments
 *
 * @link       https://personalizewp.com/
 * @since      3.2.0 Merged into PWP
 * @since      1.0.0
 *
 * @package    PersonalizeWP
 * @subpackage PersonalizeWP/Segments
 */

namespace PersonalizeWP\Segments;

use PersonalizeWP\Model\Activity;
use PersonalizeWP\Model\Segment;
use PersonalizeWP\Traits\Condition_Operator_Trait;

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

/**
 * Segments Base
 *
 * What all other Segment assigning classes extend
 */
abstract class Base {

	use Condition_Operator_Trait;

	/**
	 * Types of Activity to process, one or many.
	 *
	 * @var string[]
	 */
	protected $activity_types;

	/**
	 * Types of Segment to process, one or many.
	 *
	 * Singular Segment type can handle multiple Activity types.
	 *
	 * @var string[]
	 */
	protected $segment_types;

	/**
	 * Stores active Segments for repeated checking.
	 *
	 * @var array
	 */
	protected array $segments;

	/**
	 * Static instance.
	 *
	 * @var self
	 */
	private static $instance = null;

	/**
	 * Initialize and fetch the static instance.
	 *
	 * @return self
	 */
	public static function init() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Process an Activity record and maybe assign a Segment. Type is part of the action.
	 *
	 * @param Activity $activity Activity object
	 */
	abstract public function process_activity( $activity );

	/**
	 * Add hooks.
	 */
	public function setup() {
		// Skip auto setup if no activity types.
		if ( empty( $this->activity_types ) ) {
			return;
		}
		foreach ( $this->activity_types as $type ) {
			add_action( "personalizewp_activity_record_{$type}", array( $this, 'process_activity' ) );
		}
	}

	/**
	 * Returns the active Segments for this type.
	 */
	protected function get_segments() {
		return Segment::get_active_segments( $this->segment_types );
	}

	/**
	 * Assigns a Contact to a Segment
	 *
	 * @param int $segment_id Segment ID
	 * @param int $contact_id Contact ID
	 *
	 * @return bool
	 */
	protected function assign_contact_to_segment( int $segment_id, int $contact_id ) {
		return Segment::add_contact( $segment_id, $contact_id );
	}

	/**
	 * Removes a Contact from a Segment
	 *
	 * @since 1.1.0
	 *
	 * @param int $segment_id Segment ID
	 * @param int $contact_id Contact ID
	 *
	 * @return bool
	 */
	protected function remove_contact_from_segment( int $segment_id, int $contact_id ) {
		return Segment::remove_contact( $segment_id, $contact_id );
	}
}
