<?php
/**
 * Service Container Configuration
 *
 * Registers all services in the dependency injection container
 *
 * @since   PBOOKING_SINCE
 * @package Nemtly_Booking
 */

namespace NemtlyBooking\Core;

use NemtlyBooking\Core\Service_Provider_Manager;
use NemtlyBooking\Providers\Core_Service_Provider;
use NemtlyBooking\Providers\Repository_Service_Provider;
use NemtlyBooking\Providers\Business_Service_Provider;
use NemtlyBooking\Providers\API_Service_Provider;
use NemtlyBooking\Providers\Module_Service_Provider;
use NemtlyBooking\Providers\Payment_Service_Provider;
use NemtlyBooking\Integrations\Google\Google_OAuth_Provider;
use NemtlyBooking\Integrations\Google\Google_Calendar_Service;

/**
 * Service Container class
 *
 * @since PBOOKING_SINCE
 */
class Service_Container {
    /**
     * Container instance
     *
     * @var Container
     */
    private $container;
    /**
     * Service provider manager
     *
     * @var Service_Provider_Manager
     */
    private $provider_manager;

    /**
     * Constructor
     *
     * @since PBOOKING_SINCE
     *
     * @param Container $container Container instance.
     */
    public function __construct( Container $container ) {
        $this->container        = $container;
        $this->provider_manager = new Service_Provider_Manager( $container );
    }

    /**
     * Register all services
     *
     * @since PBOOKING_SINCE
     */
    public function register_services() {
        // Register service providers
        $this->provider_manager->register( new Core_Service_Provider() );
        $this->provider_manager->register( new Repository_Service_Provider() );
        $this->provider_manager->register( new Business_Service_Provider() );
        $this->provider_manager->register( new API_Service_Provider() );
        $this->provider_manager->register( new Module_Service_Provider() );
        $this->provider_manager->register( new Payment_Service_Provider() );
        // Allow third-party service providers to be registered
        do_action( 'nemtly_booking_register_service_providers', $this->provider_manager );
        // Allow third-party services to be registered via filter
        $additional_services = apply_filters( 'nemtly_booking_services', [] );
        foreach ( $additional_services as $service_name => $service_definition ) {
            $this->container->register( $service_name, $service_definition );
        }
    }

    /**
     * Initialize all registered services
     *
     * @since PBOOKING_SINCE
     */
    public function init_services() {
        // Boot all service providers
        $this->provider_manager->boot();
        // Initialize modules (which handle their own hooks)
        $event_module = $this->container->get( 'event_module' );
        $event_module->init();
        $booking_module = $this->container->get( 'booking_module' );
        $booking_module->init();
        // Initialize email notification service (registers event listeners)
        $this->container->get( 'email_notification_service' );
        // Initialize notification service (registers event listeners)
        $this->container->get( 'notification_service' );
        // Initialize shortcodes
        $this->container->get( 'shortcodes' );
        $this->container->get( 'dashboard_shortcode' );
        $this->container->get( 'single_event_shortcode' );
        // Initialize Google Calendar sync (registers booking hooks)
        $google_calendar_service = new Google_Calendar_Service(
            new Google_OAuth_Provider(),
            $this->container->get( 'event_repository' )
        );
        add_action( 'nemtly_booking_event_booking_confirmed', [ $google_calendar_service, 'push_booking' ] );
        add_action( 'nemtly_booking_event_booking_cancelled', [ $google_calendar_service, 'remove_booking' ] );
    }

    /**
     * Initialize REST API controllers
     *
     * @since PBOOKING_SINCE
     */
    public function init_api_controllers() {
        // Register Events Controller routes
        $events_controller = $this->container->get( 'events_controller' );
        $events_controller->register_routes();
        // Register Booking Controller routes
        $booking_controller = $this->container->get( 'booking_controller' );
        $booking_controller->register_routes();
        // Register Settings Controller routes
        $settings_controller = $this->container->get( 'settings_controller' );
        $settings_controller->register_routes();
        // Register Admin Controller routes
        $admin_controller = $this->container->get( 'admin_controller' );
        $admin_controller->register_routes();
        // Register Setup Controller routes
        $setup_controller = $this->container->get( 'setup_controller' );
        $setup_controller->register_routes();
        // Register Payment Controller routes
        $payment_controller = $this->container->get( 'payment_controller' );
        $payment_controller->register_routes();
        // Register Google Auth Controller routes
        $google_auth_controller = $this->container->get( 'google_auth_controller' );
        $google_auth_controller->register_routes();
        // Register event subscribers
        $this->register_event_subscribers();
    }

    /**
     * Register event subscribers
     *
     * @since PBOOKING_SINCE
     */
    private function register_event_subscribers() {
        $event_manager = $this->container->get( 'event_manager' );
        // Register booking event subscriber
        $booking_subscriber = new \NemtlyBooking\Subscribers\Booking_Event_Subscriber();
        $event_manager->register_subscriber( 'Booking_Event_Subscriber', $booking_subscriber );
        // Register event event subscriber
        $event_subscriber = new \NemtlyBooking\Subscribers\Event_Event_Subscriber();
        $event_manager->register_subscriber( 'Event_Event_Subscriber', $event_subscriber );
        // Record activation milestones (first event → first booking → first payment).
        Activation_Milestones::register( $event_manager );
        // Allow third-party subscribers
        do_action( 'nemtly_booking_register_event_subscribers', $event_manager );
    }

    /**
     * Get container instance
     *
     * @since PBOOKING_SINCE
     *
     * @return Container
     */
    public function get_container() {
        return $this->container;
    }

    /**
     * Get service provider manager
     *
     * @since PBOOKING_SINCE
     *
     * @return Service_Provider_Manager
     */
    public function get_provider_manager() {
        return $this->provider_manager;
    }
}
