<?php

declare(strict_types=1);

/**
 * APO-193 Card 8 — Service-layer for Section Defaults updates.
 *
 * Two underlying repositories cover the two modes:
 *   - $sectionContentDefaults: per-section-key + component-id + variant defaults
 *   - $sectionDefaults: per-component-id + variant defaults (no section-key)
 *
 * The service picks the right repository based on whether sectionKey is given.
 * Both the admin form path and the API path call this service.
 */
final class MyronSectionDefaultsActionService
{
    public function __construct(
        private readonly MyronSectionComponentDefaultsRepository $componentDefaults,
        private readonly MyronSectionContentDefaultsRepository $contentDefaults,
        private readonly MyronSectionRegistryRepository $sectionRegistry,
    ) {
    }

    /**
     * @param array<string, mixed> $content
     * @return array{componentId: string, variant: string, sectionKey: string, scope: string}
     */
    public function updateDefaults(
        string $componentId,
        string $variant,
        string $sectionKey,
        array $content,
        string $editability,
        MyronActionCallerContext $caller
    ): array {
        $componentId = trim($componentId);
        if ($componentId === '') {
            throw new InvalidArgumentException('componentId is required.');
        }
        $variant = trim($variant);
        $sectionKey = trim($sectionKey);
        $editability = $editability === '' ? 'inherit' : $editability;
        $flags = ['allowContentEditing' => $editability];
        $userId = $this->callerUserId($caller);

        if ($sectionKey !== '') {
            $this->sectionRegistry->assertGovernedSectionKey($sectionKey, 'api-section-defaults');
            $this->contentDefaults->saveDefault($sectionKey, $componentId, $variant, $content, $editability, $flags, $userId);
            $scope = 'section-key';
        } else {
            $this->componentDefaults->saveDefault($componentId, $variant, $content, $editability, $flags, $userId);
            $scope = 'component';
        }

        return [
            'componentId' => $componentId,
            'variant'     => $variant,
            'sectionKey'  => $sectionKey,
            'scope'       => $scope,
        ];
    }

    private function callerUserId(MyronActionCallerContext $caller): string
    {
        return $caller->callerType === 'human-session' ? $caller->callerId : '';
    }
}
