<?php

declare(strict_types=1);

/** APO-196 Card 4 — PATCH /api/v1/administration/site-setup */
final class MyronSaveSiteSetupAction implements MyronAction
{
    public function __construct(private readonly MyronSiteSetupActionService $service) {}
    public function metadata(): MyronActionMetadata
    {
        return new MyronActionMetadata(
            uri: '/api/v1/administration/site-setup', method: 'PATCH',
            domain: 'administration', resource: 'site-setup', verb: 'save',
            inputSchema: [
                'type' => 'object',
                'properties' => [
                    'primary_bundle_id'   => ['type' => 'string'],
                    'archetype_theme_id'  => ['type' => 'string'],
                    'active_bundle_ids'   => ['type' => 'array'],
                    'selection_manifest'  => ['type' => 'object'],
                    'apply_theme'         => ['type' => 'boolean'],
                ],
            ],
            outputSchema: ['type' => 'object', 'properties' => ['state' => ['type' => 'object'], 'destructive_required' => ['type' => 'boolean']]],
            requiredScope: MyronApiScopes::ADMINISTRATION_WRITE,
            summary: 'Save the install site-setup primary state (active bundle, archetype theme, selection manifest).',
            sideEffects: ['updates onboarding_state row'],
            preconditions: [], postconditions: ['site setup state reflects input'],
            audienceClass: 4, adminAliases: ['save-site-setup'],
            snapshotInclude: false, exposeToMcp: true,
        );
    }
    public function execute(array $input, MyronActionCallerContext $caller): MyronActionResult
    {
        try {
            $destructiveRequired = $this->service->requiresDestructiveForSiteSetupSave($input);
            if ($destructiveRequired && !$caller->holdsScope(MyronApiScopes::ADMINISTRATION_DESTRUCTIVE)) {
                return MyronActionResult::error('scope_insufficient', 'Changing the primary site type requires administration.destructive.');
            }
            $result = $this->service->saveSiteSetup($input, $caller);
            $result['destructive_required'] = $destructiveRequired;
            return MyronActionResult::ok($result);
        }
        catch (MyronActionPreconditionError $e) { return MyronActionResult::error('precondition_failed', $e->getMessage()); }
        catch (Throwable $e) { return MyronActionResult::error('business_rule_failed', $e->getMessage()); }
    }
}
