<?php

namespace KupShop\ComponentsBundle\Twig\Components\Product\Reviews\Forms;

use KupShop\CatalogBundle\Util\ReviewsUtil;
use KupShop\ComponentsBundle\Attributes\Component;
use KupShop\ComponentsBundle\Attributes\Version;
use KupShop\ComponentsBundle\Twig\ComponentInterface;
use KupShop\ComponentsBundle\Twig\Components\Product\Reviews\Types\WriteFormType;
use KupShop\ComponentsBundle\Twig\Components\Product\Reviews\Utils\WriteEntity;
use KupShop\ComponentsBundle\Twig\ComponentTrait;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Database\QueryHint;
use Query\Operator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\ComponentToolsTrait;
use Symfony\UX\LiveComponent\ComponentWithFormTrait;
use Symfony\UX\LiveComponent\DefaultActionTrait;
use Symfony\UX\TwigComponent\Attribute\PostMount;

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

    #[LiveProp]
    public int $id_product;

    #[LiveProp]
    public bool $allowAnonymous = false;

    #[LiveProp]
    public bool $alreadyRated = false;

    public function __construct(private readonly ReviewsUtil $reviewsUtil, private readonly UserContext $userContext, private readonly SessionInterface $session)
    {
    }

    protected function instantiateForm(): FormInterface
    {
        return $this->createForm(WriteFormType::class, null, [
            'action' => 'javascript:void(0);',
        ]);
    }

    #[LiveAction]
    public function handleWriteForm()
    {
        $this->submitForm();

        /** @var WriteEntity $entity */
        $entity = $this->getForm()->getData();
        $validatedData = $this->session->get('write-review-validated');

        if ($this->allowAnonymous) {
            if ($entity->email) {
                addUserEmail($entity->email, [], ['figure' => 'N', 'name' => $entity->name]);
            }
            $this->addReview($entity, ['email' => $entity->email]);
            $this->resetForm();
            $this->dispatchBrowserEvent('modal:close');
        } elseif ($validatedData && $validatedData['email'] && $validatedData['idProduct']) {
            $this->addReview($entity, $validatedData);
            $this->session->remove('write-review-validated');
            $this->resetForm();
            $this->alreadyRated = true;
            $this->dispatchBrowserEvent('modal:close');
        } else {
            addUserMessage('Údaje nejsou ověřeny', 'error');
        }
    }

    private function addReview(WriteEntity $entity, $data = null): void
    {
        $values = [
            'id_product' => $this->id_product,
            'date' => (new \DateTime())->format('Y-m-d H:i:s'),
            'rating' => $entity->rating,
            'pros' => $entity->positives ?? '',
            'cons' => $entity->negatives ?? '',
            'summary' => $entity->review ?? '',
            'figure' => ReviewsUtil::RANK_UNCONFIRMED,
        ];

        if ($data['email'] ?? false) {
            addUserEmail($data['email']);
            /** @var \User $user */
            $user = QueryHint::withRouteToMaster(fn () => \User::createFromSpec(Operator::equals(['email' => $data['email']])));
            $values['name'] = "{$user->name} {$user->surname}";
            $values['id_user'] = $user->id;
        }

        if ($data['orderNo'] ?? false) {
            $order = \Order::createFromDbOrderNo($data['orderNo']);
            $values['id_order'] = $order->id;
        }

        sqlQueryBuilder()
            ->insert('reviews')
            ->directValues($values)
            ->execute();

        addUserMessage('Recenze byla odeslána.', 'success');
    }

    #[PostMount]
    public function getHasAlreadyUserRated()
    {
        if ($this->allowAnonymous) {
            return;
        }

        $validatedData = $this->session->get('write-review-validated');

        if ($validatedData && $validatedData['email'] && $validatedData['idProduct']) {
            $this->alreadyRated = $this->reviewsUtil->hasUserAlreadyRated($validatedData['idProduct']);

            return;
        }

        $this->alreadyRated = true;
    }
}
