<?php
/**
 * Base Service Provider
 *
 * @package ZenoChatbot\Framework\Foundation
 */

namespace ZenoChatbot\Framework\Foundation;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Abstract base service provider class
 */
abstract class ServiceProvider
{
    /**
     * Application instance
     *
     * @var Application
     */
    protected $app;

    /**
     * Indicates if the provider is deferred
     *
     * @var bool
     */
    protected $defer = false;

    /**
     * Constructor
     *
     * @param Application $app
     */
    public function __construct(Application $app)
    {
        $this->app = $app;
    }

    /**
     * Register services into the container
     *
     * This method is called during the registration phase.
     * Use this to bind services, singletons, and other dependencies.
     *
     * @return void
     */
    public function register()
    {
        // Override in child classes
    }

    /**
     * Boot services after all providers have been registered
     *
     * This method is called after all service providers have been registered.
     * Use this to set up event listeners, middleware, routes, etc.
     *
     * @return void
     */
    public function boot()
    {
        // Override in child classes
    }

    /**
     * Terminate and cleanup services
     *
     * This method is called during application shutdown.
     * Use this to clean up resources, close connections, etc.
     *
     * @return void
     */
    public function terminate()
    {
        // Override in child classes
    }

    /**
     * Get the services provided by the provider
     *
     * @return array
     */
    public function provides()
    {
        return [];
    }

    /**
     * Determine if the provider is deferred
     *
     * @return bool
     */
    public function isDeferred()
    {
        return $this->defer;
    }

    /**
     * Get the application instance
     *
     * @return Application
     */
    public function getApplication()
    {
        return $this->app;
    }

    /**
     * Merge the given configuration with the existing configuration
     *
     * @param array $path
     * @param string $key
     * @return void
     */
    protected function mergeConfigFrom($path, $key)
    {
        if (!file_exists($path)) {
            return;
        }

        $config = $this->app->config()->get($key, []);
        $fileConfig = require $path;

        $this->app->config()->set($key, array_merge($fileConfig, $config));
    }

    /**
     * Load routes from the given file
     *
     * @param string $path
     * @return void
     */
    protected function loadRoutesFrom($path)
    {
        if (file_exists($path)) {
            require $path;
        }
    }

    /**
     * Load views from the given directory
     *
     * @param string $path
     * @param string $namespace
     * @return void
     */
    protected function loadViewsFrom($path, $namespace)
    {
        // For future view system implementation
        // Currently not implemented as we use Vue.js frontend
    }

    /**
     * Publish assets to the public directory
     *
     * @param array $paths
     * @param mixed $groups
     * @return void
     */
    protected function publishes(array $paths, $groups = null)
    {
        // For future asset publishing system
        // Currently handled by Vite build system
    }

    /**
     * Register a command with the application
     *
     * @param array|string $commands
     * @return void
     */
    protected function commands($commands)
    {
        $commands = is_array($commands) ? $commands : func_get_args();

        foreach ($commands as $command) {
            $this->app->bind($command);
        }
    }

    /**
     * Call after resolving callback
     *
     * @param string $name
     * @param callable $callback
     * @return void
     */
    protected function callAfterResolving($name, $callback)
    {
        $this->app->afterResolving($name, $callback);
    }
}
