<?php
/**
 * Global service provider that will responsible for all service provider
 *
 * @package Booktics/Providers
 */

namespace Booktics\Providers;

use Booktics\Admin\Admin_Service_Provider;
use Booktics\Appointment\Appointment_Service_Provider;
use Booktics\Assets\Assets_Service_Provider;
use Booktics\Cart\Cart_Service_Provider;
use Booktics\Category\Category_Service_Provider;
use Booktics\Container\Container;
use Booktics\Contracts\Provider_Contract;
use Booktics\Customer\Customer_Service_Provider;
use Booktics\Dashboard\Dashboard_Service_Provider;
use Booktics\Extensions\Extension_Service_Provider;
use Booktics\Module\Stripe_Addon\Stripe_Service_Provider;
use Booktics\Onboard\Onboard_Service_Provider;
use Booktics\Order\Order_Service_Provider;
use Booktics\Payment\Payment_Service_Provider;
use Booktics\Service\Service_Service_Provider;
use Booktics\Settings\Settings_Service_Provider;
use Booktics\Shortcode\Shortcode_Service_Provider;
use Booktics\Taxonomy\Taxonomy_Service_Provider;
use Booktics\Team_Member\Team_Member_Service_Provider;
use Booktics\Extensions\Module_Service_Provider;
use Booktics\Module\FluentCrm\FluentCRM_Service_Provider;
use Booktics\Module\Google_Calendar\Google_Service_Provider;
use Booktics\Add_To_Calendar\Add_To_Calendar_Service_Provider;

/**
 * Global_Service Provider class
 */
class Global_Service_Provider implements Provider_Contract {
    /**
     * Store container
     *
     * @var Container
     */
    protected Container $container;

    /**
     * Store service providers
     *
     * @var array<string, string>
     */
    protected array $providers = array(
        'assets'      => Assets_Service_Provider::class,
        'admin'       => Admin_Service_Provider::class,
        'appointment' => Appointment_Service_Provider::class,
        'settings'    => Settings_Service_Provider::class,
        'team-member' => Team_Member_Service_Provider::class,
        'onboard'     => Onboard_Service_Provider::class,
        'customer'    => Customer_Service_Provider::class,
        'dashboard'   => Dashboard_Service_Provider::class,
        'payment'     => Payment_Service_Provider::class,
        'service'     => Service_Service_Provider::class,
        'shortcode'   => Shortcode_Service_Provider::class,
        'category'    => Category_Service_Provider::class,
        'taxonomy'    => Taxonomy_Service_Provider::class,
        'cart'        => Cart_Service_Provider::class,
        'order'       => Order_Service_Provider::class,
        'addcalendar' => Add_To_Calendar_Service_Provider::class,
        'extension'   => Extension_Service_Provider::class,
        'module'      => Module_Service_Provider::class,
        'fluentcrm'   => FluentCRM_Service_Provider::class,
        'stripe'      => Stripe_Service_Provider::class,
        'google-calendar' => Google_Service_Provider::class,
    );

    /**
     * GlobalServiceProvider
     */
    public function __construct() {
        $this->container = booktics_container();
        $this->register();
        $this->boot();
    }

    /**
     * Register all module providers
     *
     * @return  void
     */
    public function register() {
        $providers = apply_filters( 'booktics_service_providers', $this->providers );

        if ( $providers ) {
            foreach ( $providers as $key => $provider ) {
                $this->container->addServiceProvider( $key, $provider );
            }
        }
    }

    /**
     * Boot all services from providers
     *
     * @return  void
     */
    public function boot(): void {
        $this->boot_core_services();
        $this->boot_module_services();
    }

    private function boot_core_services() {
        $services = array(
            'assets',
            'admin',
            'appointment',
            'team-member',
            'settings',
            'onboard',
            'customer',
            'dashboard',
            'payment',
            'service',
            'shortcode',
            'category',
            'taxonomy',
            'order',
            'cart',
            'extension',
            'module',
            'addcalendar',
        );

        $services = apply_filters( 'booktics_services', $services );

        foreach ( $services as $service ) {
            if ( $this->module_is_off( $service ) ) {
                continue;
            }

            $this->container->get( $service );
        }
    }

    private function boot_module_services() {
        $module_services = array(
            'google-calendar',
            'fluentcrm',
            'stripe',
        );

        foreach ( $module_services as $module ) {
            if ( $this->module_is_off( $module ) ) {
                continue;
            }

            $this->container->get( $module );
        }
    }

    /**
     * Check if module is off
     *
     * Every modules service provider will check if the module is off by module key
     * Module key and module slug is always same
     *
     * @param string $module
     * @return bool
     */
    public function module_is_off( string $module ): bool {
        $modules = booktics_modules_list();

        if ( ! isset( $modules[ $module ] ) ) {
            return false;
        }

        return ! booktics_extension()->is_enabled( $module );
    }
}
