<?php

namespace App\Core;

/**
 * BaseService — Application Service Base Class
 *
 * All application services extend this class. Services contain business logic
 * and coordinate between Models, external APIs, and other Services.
 *
 * Architecture rules (DBP v1.0 Ch.4, SAD v1.1 Ch.6):
 *   - Services contain ALL business logic. Controllers contain NO logic.
 *   - Services are responsible for data validation and transformation.
 *   - Services coordinate Models but do not execute SQL directly.
 *   - Services return plain PHP arrays or scalars — never objects.
 *   - Services must NOT output to the browser or set headers.
 *
 * Access to cross-cutting concerns:
 *   - config() — read environment/configuration values
 *   - env()    — read raw environment variables
 *   - Logger   — write to application log
 *
 * Example usage in a concrete service:
 *   class GuestService extends BaseService {
 *       private GuestModel $model;
 *
 *       public function __construct() {
 *           $this->model = new GuestModel();
 *       }
 *
 *       public function getGuestList(int $workspaceId): array {
 *           return $this->model->findAll(['workspace_id' => $workspaceId]);
 *       }
 *   }
 *
 * @package Inveetaire
 * @ref     DBP v1.0 Ch.4, SAD v1.1 Ch.6, INIT-008
 */
abstract class BaseService
{
    // ─────────────────────────────────────────────────────────────────────────
    // CONFIG + ENV ACCESS
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Read a configuration value.
     * Delegates to the global config() helper (INIT-005).
     *
     * Key format: 'file.key' or 'file.nested.key'
     * Examples:
     *   $this->config('app.name')           → 'Inveetaire'
     *   $this->config('database.host')      → '127.0.0.1'
     *   $this->config('storage.logs', '/tmp') → '/var/logs'
     *
     * @param string $key     Dot-notation config key.
     * @param mixed  $default Fallback value if key is not found.
     * @return mixed
     */
    protected function config(string $key, $default = null)
    {
        return config($key, $default);
    }

    /**
     * Read a raw environment variable.
     * Delegates to the global env() helper (INIT-005).
     *
     * @param string $key     Environment variable name (e.g. 'APP_ENV').
     * @param mixed  $default Fallback value if the variable is not set.
     * @return mixed
     */
    protected function env(string $key, $default = null)
    {
        return env($key, $default);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // LOGGING
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Write an error-level log entry.
     *
     * @param string               $message Human-readable description.
     * @param array<string, mixed> $context Optional structured context.
     * @return void
     */
    protected function logError(string $message, array $context = []): void
    {
        Logger::error($message, $context);
    }

    /**
     * Write a warning-level log entry.
     *
     * @param string               $message Human-readable description.
     * @param array<string, mixed> $context Optional structured context.
     * @return void
     */
    protected function logWarning(string $message, array $context = []): void
    {
        Logger::warning($message, $context);
    }

    /**
     * Write an info-level log entry.
     *
     * @param string               $message Human-readable description.
     * @param array<string, mixed> $context Optional structured context.
     * @return void
     */
    protected function logInfo(string $message, array $context = []): void
    {
        Logger::info($message, $context);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // APP INFO
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Return the current application environment.
     *
     * @return string  'local', 'staging', or 'production'
     */
    protected function getEnvironment(): string
    {
        return (string) $this->config('app.env', 'local');
    }

    /**
     * Return true when running in the local development environment.
     *
     * @return bool
     */
    protected function isLocal(): bool
    {
        return $this->getEnvironment() === 'local';
    }

    /**
     * Return true when running in the production environment.
     *
     * @return bool
     */
    protected function isProduction(): bool
    {
        return $this->getEnvironment() === 'production';
    }
}
