<?php

declare(strict_types = 1);

namespace Component\Posting\Controller;

use App\Core;
use App\Core\Controller;
use App\Core\Event;
use function App\Core\I18n\_m;
use App\Core\VisibilityScope;
use App\Util\Common;
use App\Util\Exception\ClientException;
use Component\Posting\Form;
use Symfony\Component\HttpFoundation\File\Exception\FormSizeFileException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;

class Posting extends Controller
{
    public function onPost(Request $request): RedirectResponse
    {
        $actor = Common::actor();
        $form  = Form\Posting::create($request);

        $form->handleRequest($request);
        if ($form->isSubmitted()) {
            try {
                if ($form->isValid()) {
                    $data = $form->getData();
                    Event::handle('PostingModifyData', [$request, $actor, &$data, $form]);

                    if (empty($data['content']) && empty($data['attachments'])) {
                        // TODO Display error: At least one of `content` and `attachments` must be provided
                        throw new ClientException(_m('You must enter content or provide at least one attachment to post a note.'));
                    }

                    if (\is_null(VisibilityScope::tryFrom($data['visibility']))) {
                        throw new ClientException(_m('You have selected an impossible visibility.'));
                    }

                    $extra_args = [];
                    Event::handle('AddExtraArgsToNoteContent', [$request, $actor, $data, &$extra_args, $form]);

                    if (\array_key_exists('in', $data) && $data['in'] !== 'public') {
                        $target = $data['in'];
                    }

                    \Component\Posting\Posting::storeLocalNote(
                        actor: $actor,
                        content: $data['content'],
                        content_type: $data['content_type'],
                        locale: $data['language'],
                        scope: VisibilityScope::from($data['visibility']),
                        attentions: isset($target) ? [$target] : [],
                        reply_to: \array_key_exists('reply_to_id', $data) ? $data['reply_to_id'] : null,
                        attachments: $data['attachments'],
                        process_note_content_extra_args: $extra_args,
                    );

                    return Core\Form::forceRedirect($form, $request);
                }
            } catch (FormSizeFileException $e) {
                throw new ClientException(_m('Invalid file size given.'), previous: $e);
            }
        }
        throw new ClientException(_m('Invalid form submission.'));
    }
}
