<?php

declare(strict_types = 1);

namespace Plugin\Pinboard\Controller;

use App\Core\Cache;
use App\Core\Controller;
use App\Core\DB;
use App\Core\Form;
use function App\Core\I18n\_m;
use App\Core\Router;
use App\Util\Common;
use App\Util\Exception\BugFoundException;
use App\Util\Exception\ClientException;
use Plugin\Pinboard as P;
use Plugin\Pinboard\Entity\Token;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\SubmitButton;
use Symfony\Component\HttpFoundation\Request;

class Settings extends Controller
{
    public static function setup()
    {
        $user    = Common::ensureLoggedIn();
        $token   = Token::get(id: null, token: null, user: $user);
        $enabled = ($token?->getEnabled() ?? false);
        $form    = Form::create([
            ['token', TextType::class, ['label' => _m('The token used to authenticate you via the Pinboard-compatible API'), 'data' => $token?->getUserTokenString(), 'disabled' => true]],
            ['enable', SubmitType::class, ['label' => $enabled ? _m('Disable') : _m('Enable'), 'attr' => ['alt' => $enabled ? _m('Disable the use of the Pinboard-compatible API') : _m('Enable the use of the Pinboard-compatible API')]]],
            ['regenerate', SubmitType::class, ['label' => _m('Regenerate Token'), 'disabled' => !$enabled]],
        ], form_options: ['action' => Router::url(P\Pinboard::controller_route)]);

        return [
            '_template'   => 'pinboard/settings.html.twig',
            'form_view'   => $form->createView(),
            'form'        => $form,
            'token'       => $token,
            'was_enabled' => $enabled,
        ];
    }

    public static function onPost(Request $request)
    {
        $user   = Common::ensureLoggedIn();
        $params = self::setup();
        $form   = $params['form'];
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            /** @var SubmitButton $enable_button */
            $enable_button = $form->get('enable');
            /** @var SubmitButton $regenerate_button */
            $regenerate_button = $form->get('regenerate');
            /** @var Token $token */
            $token = $params['token'];
            if ($enable_button->isClicked()) {
                if ($params['was_enabled']) {
                    if (\is_null($params['token'])) {
                        throw new BugFoundException('Pinboard API can not be enabled if no token is present');
                    } else {
                        DB::refresh($token);
                        $token->setEnabled(false);
                    }
                } else {
                    if (\is_null($params['token'])) {
                        DB::persist($token = Token::create(['actor_id' => $user->getId(), 'token' => Token::generateTokenString(), 'enabled' => true]));
                    } else {
                        DB::refresh($params['token']);
                        $token->setEnabled(true);
                    }
                }
            } elseif ($regenerate_button->isClicked()) {
                if (\is_null($params['token'])) {
                    throw new ClientException(_m('Can not regenerate token when no token exists. Enable Pinboard first'));
                } else {
                    DB::refresh($params['token']);
                    $token->setToken(Token::generateTokenString());
                }
            } else {
                throw new ClientException(_m('Invalid form submission'));
            }
            Cache::set(Token::cacheKeys($user->getId())['user-token'], $token);
            DB::flush();
            return Form::forceRedirect($form, $request);
        }
        throw new ClientException(_m('Do not GET this page'));
    }
}
