<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CmsBundle\Components\SignIn;

use Ferienpass\CmsBundle\Form\UserLoginType;
use Ferienpass\CmsBundle\Security\LoginRedirectResolver;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\ComponentWithFormTrait;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent(template: '@Contao/components/sign_in/login.html.twig', route: 'live_component_cms')]
class Login extends AbstractController
{
    use ComponentWithFormTrait;
    use DefaultActionTrait;

    /**
     * Canonical post-login target passed by the includer (e.g. the application
     * form, which knows the offer's reader URL). Used for the passkey redirect,
     * where the in-fragment Referer is unreliable. Only consumed for the
     * passkey flow — the password flow keeps the signed {@see targetPath()}.
     */
    #[LiveProp]
    public ?string $redirect = null;

    public function __construct(private readonly LoginRedirectResolver $redirectResolver)
    {
    }

    public function targetPath(Request $request): string
    {
        // If the form was submitted and the credentials were wrong, take the target
        // path from the submitted data as otherwise it would take the current page
        if ($request->isMethod('POST') && $request->request->has('_target_path')) {
            $targetPath = base64_decode((string) $request->request->get('_target_path'), true) ?: null;
            if (null !== $targetPath) {
                return $targetPath;
            }
        }

        // Signed `?redirect=` or current page — never a raw unsigned redirect.
        return $this->redirectResolver->resolve();
    }

    protected function instantiateForm(): FormInterface
    {
        return $this->createForm(UserLoginType::class);
    }

    /**
     * Disable automatic live model binding for the login form: it is submitted
     * by the Stimulus controller (JSON to /check_login), not via live, and its
     * username/password fields use bare names (no form prefix) which are not
     * valid live model names.
     */
    private function getDataModelValue(): ?string
    {
        return null;
    }
}
