<?php

declare(strict_types=1);

final class MyronExportSiteSnapshotAction implements MyronAction
{
    public function __construct(private readonly MyronSiteSnapshotExportService $service)
    {
    }

    public function metadata(): MyronActionMetadata
    {
        return new MyronActionMetadata(
            uri: '/api/v1/site/snapshot/export',
            method: 'GET',
            domain: 'administration',
            resource: 'site-snapshot',
            verb: 'export',
            inputSchema: ['type' => 'object', 'properties' => []],
            outputSchema: [
                'type' => 'object',
                'properties' => [
                    'snapshot' => ['type' => 'object'],
                    'filename' => ['type' => 'string'],
                ],
            ],
            requiredScope: MyronApiScopes::ADMINISTRATION_READ,
            summary: 'Export the operator-owned site state as a portable JSON snapshot envelope.',
            sideEffects: [],
            preconditions: ['caller holds administration.read'],
            postconditions: ['snapshot envelope returned with SHA-256 integrity hash'],
            audienceClass: 2,
            adminAliases: ['export-site-snapshot'],
            snapshotInclude: false,
            exposeToMcp: true,
        );
    }

    public function execute(array $input, MyronActionCallerContext $caller): MyronActionResult
    {
        try {
            $snapshot = $this->service->export();
            $timestamp = preg_replace('/[^0-9A-Za-z]+/', '-', (string) ($snapshot['exportedAt'] ?? myronNow()));
            $filename = 'myroncms-site-snapshot-' . trim((string) $timestamp, '-') . '.json';
            return MyronActionResult::ok([
                'snapshot' => $snapshot,
                'filename' => $filename,
            ]);
        } catch (Throwable $e) {
            return MyronActionResult::error('export_failed', $e->getMessage());
        }
    }
}
