<?php

declare(strict_types=1);

/**
 * APO-194 Card 3 — Document Template action service.
 *
 * Three operator verbs: upload (which uploads a file AND creates a template
 * referencing the file), update (rewrites template metadata), deactivate
 * (marks template inactive). The admin form path and the API path share this
 * service.
 *
 * Note: the upload verb requires the canonical JsonContentEnvelope (or
 * traditional multipart $_FILES) — both produce the same file row via
 * MyronFileRepository::uploadFile. The service accepts the file_id after
 * upload has happened. The API entry point (POST /api/v1/design/document-templates)
 * accepts either (a) an inline JSON-content envelope to upload + bind in one
 * call, or (b) a pre-existing file_id when the caller has uploaded
 * separately via the Files action.
 */
final class MyronDocumentTemplateActionService
{
    public function __construct(
        private readonly MyronDocumentTemplateRepository $templates,
    ) {
    }

    /**
     * Create a document template from an already-uploaded file row.
     *
     * @param array<string, mixed> $input  template metadata payload (name, description, slug, etc.)
     * @return array<string, mixed>
     */
    public function createFromFile(string $fileId, array $input, MyronActionCallerContext $caller): array
    {
        $fileId = trim($fileId);
        if ($fileId === '') {
            throw new InvalidArgumentException('fileId is required.');
        }
        return (array) $this->templates->createFromFile($fileId, $input, $this->callerUserId($caller));
    }

    /**
     * @param array<string, mixed> $input
     * @return array{templateId: string}
     */
    public function update(string $templateId, array $input, MyronActionCallerContext $caller): array
    {
        $templateId = trim($templateId);
        if ($templateId === '') {
            throw new InvalidArgumentException('templateId is required.');
        }
        $this->templates->updateTemplate($templateId, $input);
        return ['templateId' => $templateId];
    }

    /**
     * @return array{templateId: string, deactivated: bool}
     */
    public function deactivate(string $templateId, MyronActionCallerContext $caller): array
    {
        $templateId = trim($templateId);
        if ($templateId === '') {
            throw new InvalidArgumentException('templateId is required.');
        }
        $this->templates->deactivateTemplate($templateId);
        return ['templateId' => $templateId, 'deactivated' => true];
    }

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