<?php
/**
 * Class Noesia Cs Plugin.
 *
 * @package Noesia_Commerce_Suite
 */

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

/**
 * Class implementation.
 */
class Noesia_CS_Plugin {
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private static $instance = null;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $container;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $order_repository;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $product_repository;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $passport_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $analytics_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $warranty_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $doctor_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $impact_map_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $email_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $reorder_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $data_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $feature_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $system_status_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $care_action_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $settings_binding_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $service_boundary_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $weather_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $admin_search_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $commerce_view_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $public;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $admin;

	/**
	 * Handles the related plugin operation.
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Handles the related plugin operation.
	 */
	private function __construct() {}

	/**
	 * Handles the related plugin operation.
	 */
	public function init() {
		$this->container          = new Noesia_CS_Container();
		$this->order_repository   = new Noesia_CS_Order_Repository();
		$this->product_repository = new Noesia_CS_Product_Repository();
		$this->passport_service   = new Noesia_CS_Passport_Service( $this->order_repository );
		$this->warranty_service   = new Noesia_CS_Warranty_Service();
		$this->analytics_service  = new Noesia_CS_Analytics_Service( $this->warranty_service, $this->order_repository );
		$this->doctor_service     = new Noesia_CS_Doctor_Service( $this->product_repository );
		$this->impact_map_service = new Noesia_CS_Impact_Map_Service( $this->order_repository );
		$this->email_service      = new Noesia_CS_Email_Service( $this->passport_service );
		$this->reorder_service    = new Noesia_CS_Reorder_Service( $this->passport_service, $this->email_service, $this->order_repository );
		$this->data_service       = new Noesia_CS_Data_Service();
		$this->feature_service    = new Noesia_CS_Feature_Service();
		$this->system_status_service = new Noesia_CS_System_Status_Service();
		$this->care_action_service = new Noesia_CS_Care_Action_Service();
		$this->settings_binding_service = new Noesia_CS_Settings_Binding_Service();
		$this->service_boundary_service = new Noesia_CS_Service_Boundary_Service();
		$this->weather_service = new Noesia_CS_Weather_Service();
		$this->admin_search_service = new Noesia_CS_Admin_Search_Service( $this->passport_service, $this->order_repository, $this->product_repository );
		$this->commerce_view_service = new Noesia_CS_Commerce_View_Service( $this->order_repository, $this->passport_service );

		$this->register_container_items();
		$this->public             = new Noesia_CS_Public( $this->passport_service, $this->warranty_service, $this->impact_map_service, $this->email_service, $this->reorder_service, $this->care_action_service );
		$this->admin              = new Noesia_CS_Admin( $this->passport_service, $this->analytics_service, $this->doctor_service, $this->impact_map_service, $this->email_service, $this->reorder_service, $this->data_service, $this->feature_service, $this->system_status_service, $this->care_action_service, $this->settings_binding_service, $this->container );

		$this->public->hooks();
		$this->admin->hooks();

		add_action( Noesia_CS_Reorder_Service::CRON_HOOK, array( $this->reorder_service, 'run_scheduled_cycle' ) );

		add_filter( 'query_vars', array( $this, 'query_vars' ) );
		add_action( 'init', array( $this, 'rewrite_rules' ) );
		add_action( 'admin_notices', array( $this, 'woocommerce_notice' ) );
	}


	/**
	 * Handles the related plugin operation.
	 */
	private function register_container_items() {
		if ( ! $this->container ) {
			return;
		}

		$this->container->set( 'order_repository', $this->order_repository );
		$this->container->set( 'product_repository', $this->product_repository );
		$this->container->set( 'passport_service', $this->passport_service );
		$this->container->set( 'warranty_service', $this->warranty_service );
		$this->container->set( 'analytics_service', $this->analytics_service );
		$this->container->set( 'doctor_service', $this->doctor_service );
		$this->container->set( 'impact_map_service', $this->impact_map_service );
		$this->container->set( 'email_service', $this->email_service );
		$this->container->set( 'reorder_service', $this->reorder_service );
		$this->container->set( 'data_service', $this->data_service );
		$this->container->set( 'feature_service', $this->feature_service );
		$this->container->set( 'system_status_service', $this->system_status_service );
		$this->container->set( 'care_action_service', $this->care_action_service );
		$this->container->set( 'settings_binding_service', $this->settings_binding_service );
		$this->container->set( 'service_boundary_service', $this->service_boundary_service );
		$this->container->set( 'weather_service', $this->weather_service );
		$this->container->set( 'admin_search_service', $this->admin_search_service );
		$this->container->set( 'commerce_view_service', $this->commerce_view_service );
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function container() {
		return $this->container;
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $key Key.
	 */
	public function service( $key ) {
		return $this->container ? $this->container->get( $key ) : null;
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function feature_service() {
		if ( ! $this->feature_service ) {
			$this->feature_service = new Noesia_CS_Feature_Service();
		}
		return $this->feature_service;
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $vars Vars.
	 */
	public function query_vars( $vars ) {
		$vars[] = 'noesia_cs_care_token';
		$vars[] = 'noesia_cs_reorder_optout_token';
		$vars[] = 'noesia_cs_care_action_token';
		$vars[] = 'noesia_cs_care_action_type';
		return $vars;
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function rewrite_rules() {
		add_rewrite_rule( '^noesia-care/([^/]+)/?$', 'index.php?noesia_cs_care_token=$matches[1]', 'top' );
		add_rewrite_rule( '^noesia-reorder-opt-out/([^/]+)/?$', 'index.php?noesia_cs_reorder_optout_token=$matches[1]', 'top' );
		add_rewrite_rule( '^noesia-care-action/([^/]+)/([^/]+)/?$', 'index.php?noesia_cs_care_action_token=$matches[1]&noesia_cs_care_action_type=$matches[2]', 'top' );
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function woocommerce_notice() {
		if ( class_exists( 'WooCommerce' ) ) {
			return;
		}
		if ( ! current_user_can( 'activate_plugins' ) ) {
			return;
		}
		printf(
			'<div class="notice notice-warning"><p><strong>%s</strong> %s</p></div>',
			esc_html__( 'Noesia Commerce Suite:', 'noesia-commerce-suite' ),
			esc_html__( 'WooCommerce is required for commerce features. The admin UI can load, but passports, analytics and order care tools need WooCommerce active.', 'noesia-commerce-suite' )
		);
	}
}
