<?php

declare(strict_types=1);

namespace App\Factories;

use Slim\Views\Twig;
use Twig\Loader\FilesystemLoader;
use Medoo\Medoo;
use Dotenv\Dotenv;
use App\Repositories\PostRepositoryMedoo;
use App\Repositories\PostRepositoryInterface;

/**
 * Fabrique des services de l'application.
 *
 * Cette fabrique centralise la création des dépendances (Twig, DB, repositories...)
 * pour garder public/index.php minimal et faciliter les tests/unit.
 */
final class ServiceFactory
{
    /**
     * Crée et retourne un tableau associatif de services.
     *
     * Clefs retournées :
     * - 'view' => Twig
     * - 'postRepository' => PostRepositoryInterface
     *
     * @param array<string,mixed>|null $overrides Permet d'injecter des remplacements pour les tests.
     * @return array<string,mixed>
     */
    public static function createServices(?array $overrides = null): array
    {
        // Charger .env si présent (tolérant l'absence)
        $dotenv = Dotenv::createImmutable(__DIR__ . '/../../');
        $dotenv->safeLoad();

        // Config basique (idem que précédemment mais centralisé)
        $env = strtolower((string) ($_ENV['APP_ENV'] ?? $_SERVER['APP_ENV'] ?? 'production'));
        $devEnvs = ['development', 'dev'];
        $twigCacheEnv = $_ENV['TWIG_CACHE'] ?? $_SERVER['TWIG_CACHE'] ?? null;
        if ($twigCacheEnv !== null && $twigCacheEnv !== '') {
            $twigCache = (string)$twigCacheEnv;
        } else {
            $twigCache = in_array($env, $devEnvs, true) ? false : __DIR__ . '/../../var/cache/twig';
        }

        $dbFile = $_ENV['DB_FILE'] ?? __DIR__ . '/../../database/app.sqlite';
        $dbFileMode = 0664;

        // Créer dossier cache si nécessaire
        if ($twigCache && $twigCache !== false && !is_dir((string) $twigCache)) {
            @mkdir((string) $twigCache, 0755, true);
        }

        // Twig
        $loader = new FilesystemLoader(__DIR__ . '/../../views');
        $twig = new Twig($loader, ['cache' => $twigCache]);

        // Medoo (SQLite)
        $dbDir = dirname($dbFile);
        if (!is_dir($dbDir)) {
            @mkdir($dbDir, 0755, true);
        }
        if (!file_exists($dbFile)) {
            @touch($dbFile);
            @chmod($dbFile, $dbFileMode);
        }

        $medooOptions = [
            'database_type' => 'sqlite',
            'database_name' => $dbFile,
            'charset' => 'utf8',
        ];
        $database = new Medoo($medooOptions);

        // Repository
        $postRepository = new PostRepositoryMedoo($database);

        $services = [
            'view' => $twig,
            'database' => $database,
            'postRepository' => $postRepository,
        ];

        // Appliquer overrides si fournis (utile pour tests)
        if (is_array($overrides)) {
            $services = array_merge($services, $overrides);
        }

        return $services;
    }
}
 