<?php

declare(strict_types=1);

final class MyronDownloadPageMarkdownAction implements MyronAction
{
    public function __construct(
        private readonly MyronContentRepository $repository,
        private readonly MyronMarkdownExtractor $extractor,
    ) {
    }

    public function metadata(): MyronActionMetadata
    {
        return new MyronActionMetadata(
            uri: '/api/v1/content/pages/{pageId}/markdown',
            method: 'GET',
            domain: 'content',
            resource: 'page-markdown',
            verb: 'downloadMarkdown',
            inputSchema: [
                'type' => 'object',
                'properties' => ['pageId' => ['type' => 'string']],
                'required' => ['pageId'],
            ],
            outputSchema: [
                'type' => 'object',
                'properties' => [
                    'filename' => ['type' => 'string'],
                    'contentType' => ['type' => 'string'],
                    'body' => ['type' => 'string'],
                ],
            ],
            requiredScope: MyronApiScopes::CONTENT_READ,
            summary: 'Download a published page as Markdown with YAML front matter for AI agent consumption.',
            sideEffects: [],
            preconditions: ['page exists', 'page is published', 'effective indexability is true'],
            postconditions: ['text/markdown body returned as downloadable markdown'],
            audienceClass: 3,
            adminAliases: ['pages.downloadMarkdown'],
            snapshotInclude: false,
            exposeToMcp: true,
        );
    }

    public function execute(array $input, MyronActionCallerContext $caller): MyronActionResult
    {
        $pageId = trim((string) ($input['pageId'] ?? ''));
        if ($pageId === '') {
            return MyronActionResult::error('input_invalid', 'pageId is required.');
        }

        $page = $this->repository->getPublishedPageById($pageId);
        if (!is_array($page)) {
            return MyronActionResult::error('not_found', 'Published page not found.');
        }

        if (!$this->repository->isPageMarkupDownloadable($page)) {
            return MyronActionResult::error(
                'not_indexable',
                'This page type is not available for markdown download. Specialty content like funnels is excluded by site policy.'
            );
        }

        return MyronActionResult::ok([
            'filename' => $this->filenameForPage($page),
            'contentType' => 'text/markdown; charset=utf-8',
            'body' => $this->extractor->extract($page),
        ]);
    }

    /**
     * @param array<string, mixed> $page
     */
    private function filenameForPage(array $page): string
    {
        $slug = trim((string) ($page['slug'] ?? ''));
        $path = trim((string) ($page['path'] ?? ''));
        if ($path === '/' || $slug === '' || $slug === 'home') {
            return 'index.md';
        }

        $source = trim($path, '/');
        if ($source === '') {
            $source = $slug;
        }
        $safe = preg_replace('/[^a-z0-9_-]+/i', '-', str_replace('/', '-', $source)) ?: 'page';
        return trim($safe, '-') . '.md';
    }
}
