<?php

declare(strict_types=1);

namespace App\Framework\Vite\ValueObjects;

/**
 * Value Object for Vite configuration
 *
 * Holds configuration for Vite integration including paths,
 * dev server settings, and entrypoint configuration.
 */
final readonly class ViteConfig
{
    /**
     * @param string $buildDirectory Directory where Vite outputs files (relative to public/)
     * @param string $manifestFileName Name of the manifest file
     * @param string $devServerUrl URL of the Vite dev server
     * @param array<string> $entrypoints Default entrypoints to load
     * @param string|null $nonce CSP nonce for inline scripts
     * @param bool $hotReload Whether to enable hot module replacement in dev
     */
    public function __construct(
        public string $buildDirectory = 'assets',
        public string $manifestFileName = '.vite/manifest.json',
        public string $devServerUrl = 'https://localhost:3000',
        public array $entrypoints = ['main'],
        public ?string $nonce = null,
        public bool $hotReload = true
    ) {
    }

    /**
     * Get the full manifest path relative to public directory
     */
    public function getManifestPath(string $publicPath): string
    {
        return rtrim($publicPath, '/') . '/' . ltrim($this->manifestFileName, '/');
    }

    /**
     * Get the dev server entry URL
     */
    public function getDevServerEntry(string $entry): string
    {
        return rtrim($this->devServerUrl, '/') . '/' . ltrim($entry, '/');
    }

    /**
     * Get the Vite client URL for HMR
     */
    public function getViteClientUrl(): string
    {
        return rtrim($this->devServerUrl, '/') . '/@vite/client';
    }

    /**
     * Create config with custom entrypoints
     *
     * @param array<string> $entrypoints
     */
    public function withEntrypoints(array $entrypoints): self
    {
        return new self(
            buildDirectory: $this->buildDirectory,
            manifestFileName: $this->manifestFileName,
            devServerUrl: $this->devServerUrl,
            entrypoints: $entrypoints,
            nonce: $this->nonce,
            hotReload: $this->hotReload
        );
    }

    /**
     * Create config with CSP nonce
     */
    public function withNonce(string $nonce): self
    {
        return new self(
            buildDirectory: $this->buildDirectory,
            manifestFileName: $this->manifestFileName,
            devServerUrl: $this->devServerUrl,
            entrypoints: $this->entrypoints,
            nonce: $nonce,
            hotReload: $this->hotReload
        );
    }
}
