<?php

namespace KupShop\CommentsBundle\Twig\Components\Comments\Forms;

use KupShop\CommentsBundle\Twig\Components\Comments\Types\FormType;
use KupShop\CommentsBundle\Twig\Components\Comments\Utils\Entity;
use KupShop\CommentsBundle\Util\CommentsUtil;
use KupShop\ComponentsBundle\Attributes\Component;
use KupShop\ComponentsBundle\Attributes\Version;
use KupShop\ComponentsBundle\Twig\ComponentInterface;
use KupShop\ComponentsBundle\Twig\ComponentTrait;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveListener;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\ComponentToolsTrait;
use Symfony\UX\LiveComponent\ComponentWithFormTrait;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent(template: '@Comments/components/Comments/Forms/Form.1.html.twig', csrf: false)]
#[Component(1, [
    new Version(1),
])]
class Form extends AbstractController implements ComponentInterface
{
    use ComponentTrait;
    use DefaultActionTrait;
    use ComponentWithFormTrait;
    use ComponentToolsTrait;

    #[LiveProp]
    public ?int $id_product = null;

    #[LiveProp]
    public ?int $id_article = null;

    #[LiveProp]
    public ?int $id_parent = null;

    #[LiveProp]
    public ?string $ref_comment = null;

    #[LiveProp]
    public ?string $ref_name = null;

    #[LiveProp]
    public bool $renderLoginForm = false;

    public function __construct(
        private readonly CommentsUtil $commentsUtil,
        private readonly UserContext $userContext,
        private readonly TranslatorInterface $translator,
        private readonly SentryLogger $sentryLogger,
    ) {
    }

    protected function instantiateForm(): FormInterface
    {
        $validationGroups = ['Default'];

        if (!$this->userContext->getActiveId()) {
            $validationGroups[] = FormType::NOT_LOGGED_GROUP;
        }

        return $this->createForm(FormType::class, null, [
            'action' => 'javascript:void(0);',
            'validation_groups' => $validationGroups,
        ]);
    }

    #[LiveAction]
    public function handleForm(): void
    {
        try {
            $this->submitForm();

            /** @var Entity $entity */
            $entity = $this->getForm()->getData();

            if ($this->getIsUserLoggedIn()) {
                $userId = $this->userContext->getActiveId();
            } elseif (findModule(\Modules::COMMENTS, \Modules::SUB_COMMENTS_ANONYMOUS) && !Contexts::get(UserContext::class)->getActive()) {
                $userId = addUserEmail($entity->email, [], ['figure' => 'N', 'name' => $entity->name]);
            } else {
                addUserMessage($this->translator->trans('anonymous.not.allowed', [], 'comments'), 'error');

                throw new \Exception('Není povoleno vkládat anonymní komentáře');
            }

            if (!empty($this->id_product)) {
                $this->commentsUtil->addComment($this->id_product, 'product', $entity->comment, $this->id_parent, $userId);
            } elseif (!empty($this->id_article)) {
                $this->commentsUtil->addComment($this->id_article, 'article', $entity->comment, $this->id_parent, $userId);
            } else {
                throw new \Exception('ID product or article not found');
            }

            $this->resetForm();
            addUserMessage($this->translator->trans('successfully.submitted', [], 'comments'), 'success');
            $this->dispatchBrowserEvent('modal:close');
        } catch (\Exception $e) {
            try {
                $commentOptions = $this->getForm()->get('comment')->getConfig()->getRequired();
                $nameOptions = $this->getForm()->get('name')->getConfig()->getRequired();
                $emailOptions = $this->getForm()->get('email')->getConfig()->getRequired();
            } catch (\Exception $e) {
            }

            $this->sentryLogger->captureException($e, ['extra' => [
                'errors' => (string) $this->getForm()->getErrors(true, true),
                'userActiveId' => $this->userContext->getActiveId(),
                'nameEmailRequired' => !$this->userContext->getActiveId(),
                'userIsActive' => $this->userContext->isActive(),
                'commentRequired' => $commentOptions ?? null,
                'nameRequired' => $nameOptions ?? null,
                'emailRequired' => $emailOptions ?? null,
                'postData' => $_POST ?? null,
            ]]);
        }
        $this->dispatchBrowserEvent('button:loading:disable');
    }

    #[LiveAction]
    public function handleOpenLogin(): void
    {
        $this->renderLoginForm = true;
    }

    #[LiveListener('loginParentChecked')]
    public function handleLoginAction(): void
    {
        $this->renderLoginForm = false;
    }

    public function getIsAllowedAnonymous(): bool
    {
        return !empty(findModule(\Modules::COMMENTS, \Modules::SUB_COMMENTS_ANONYMOUS)) && \Settings::getDefault()['comment_verified_only'] == 'N';
    }

    public function getIsUserLoggedIn(): bool
    {
        return !empty($this->userContext->getActiveId());
    }

    public function getShopMail(): string
    {
        return \Settings::getDefault()->shop_email ?? '';
    }
}
