<?php

declare(strict_types=1);

final class MyronUpdatePageSectionContentAction implements MyronAction
{
    public function __construct(private readonly MyronPageContractService $service) {}

    public function metadata(): MyronActionMetadata
    {
        return new MyronActionMetadata(
            uri: '/api/v1/content/pages/{pageId}/sections/{sectionInstanceKey}/content',
            method: 'PATCH',
            domain: 'content',
            resource: 'page-section',
            verb: 'update',
            inputSchema: [
                'type' => 'object',
                'properties' => [
                    'pageId' => ['type' => 'string'],
                    'sectionInstanceKey' => ['type' => 'string'],
                    'fields' => ['type' => 'object'],
                    'publish' => ['type' => 'boolean'],
                    'publishedAt' => ['type' => 'string'],
                ],
                'required' => ['pageId', 'sectionInstanceKey', 'fields'],
            ],
            outputSchema: [
                'type' => 'object',
                'properties' => [
                    'pageId' => ['type' => 'string'],
                    'sectionInstanceKey' => ['type' => 'string'],
                    'fieldsUpdated' => ['type' => 'array'],
                ],
            ],
            requiredScope: MyronApiScopes::CONTENT_WRITE,
            summary: 'Update page section content by Page Contract address. Validates section, field names, types, and asset kind before saving a new draft page version. For rich body fields, bodyMarkdown is converted to sanitized HTML.',
            sideEffects: ['inserts new page_versions row', 'updates pages.current_draft_version_id', 'optionally publishes page'],
            preconditions: ['page exists', 'section exists in Page Contract', 'fields are editable by contract'],
            postconditions: ['page content remains human-editable through the same side sheet fields'],
            audienceClass: 4,
            snapshotInclude: false,
            exposeToMcp: true,
        );
    }

    public function execute(array $input, MyronActionCallerContext $caller): MyronActionResult
    {
        try {
            $fields = is_array($input['fields'] ?? null) ? (array) $input['fields'] : [];
            return MyronActionResult::ok($this->service->updateSectionContent(
                (string) ($input['pageId'] ?? ''),
                (string) ($input['sectionInstanceKey'] ?? ''),
                $fields,
                (bool) ($input['publish'] ?? false),
                isset($input['publishedAt']) ? (string) $input['publishedAt'] : null
            ));
        } catch (MyronActionPreconditionError $e) {
            return MyronActionResult::error('precondition_failed', $e->getMessage());
        } catch (InvalidArgumentException $e) {
            return MyronActionResult::error('input_invalid', $e->getMessage());
        } catch (Throwable $e) {
            return MyronActionResult::error('business_rule_failed', $e->getMessage());
        }
    }
}
