<?php

namespace KupShop\WatchdogBundle\Controller;

use KupShop\ContentBundle\Util\Captcha;
use KupShop\ContentBundle\View\Exception\ValidationException;
use KupShop\KupShopBundle\Routing\SimpleTranslatedRoute;
use KupShop\KupShopBundle\Routing\TranslatedRoute;
use KupShop\KupShopBundle\Util\Mail\EmailCheck;
use KupShop\KupShopBundle\Views\Traits\MessagesTrait;
use KupShop\WatchdogBundle\Util\Watchdog;
use KupShop\WatchdogBundle\View\WatchdogView;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class WatchdogController extends AbstractController
{
    use MessagesTrait;

    private Watchdog $watchdog;
    private EmailCheck $emailCheck;

    public function __construct(Watchdog $watchdog, EmailCheck $emailCheck)
    {
        $this->watchdog = $watchdog;
        $this->emailCheck = $emailCheck;
    }

    /**
     * @SimpleTranslatedRoute("watchdog-list")
     */
    public function watchdogAction(Request $request, WatchdogView $view): Response
    {
        $view->setFilterData($request->get('dynamic_filter', []));

        return $view->getResponse($request);
    }

    /**
     * @TranslatedRoute("/#watchdog-list#/pridat/")
     */
    public function addAction(Request $request): Response
    {
        return $this->getResponse($request, 'add');
    }

    /**
     * @TranslatedRoute("/#watchdog-list#/odebrat/")
     */
    public function removeAction(Request $request): Response
    {
        return $this->getResponse($request, 'remove');
    }

    /**
     * @TranslatedRoute("/#watchdog-list#/odebrat-podle-uzivatele/")
     */
    public function userRemoveAction(Request $request): Response
    {
        $userId = $request->get('id_user');
        $productId = $request->get('id_product');
        $variationId = $request->get('id_variation');
        $hash = $request->get('hash');

        if (empty($userId) || $hash != $this->watchdog->getWatchdogHash($userId, $productId, $variationId)) {
            throw new NotFoundHttpException();
        }

        $this->watchdog->dropWatchdog($userId, $productId, $variationId);

        if (isAjax()) {
            return new JsonResponse([
                'success' => true,
                'error' => null,
            ]);
        }

        $this->addSuccessMessage(translate('watchdogUserRemoveSuccess', 'watchdog'));

        return new RedirectResponse(
            path('kupshop_content_usermessage_usermessage')
        );
    }

    private function getResponse(Request $request, $type): Response
    {
        $email = $request->get('email');

        if ($response = $this->doCheck($request, $email)) {
            return $response;
        }

        $user = \User::getCurrentUser();
        // if user is not logged
        if (!$user) {
            $fields = ['figure' => 'N'];
            $get_news = $request->get('news');
            if ($get_news) {
                $fields['get_news'] = $get_news;
            }
            $userId = addUserEmail($email, ['Hlídací pes'], $fields);
        } else {
            $userId = $user->id;
        }

        $productId = $this->getProductId($request);
        $variationId = $this->getVariationId($request);
        $price = $this->getPrice($request);
        $availability = $this->getAvailability($request);

        if ($productId) {
            switch ($type) {
                case 'add':
                    $this->watchdog->addWatchdog((int) $userId, $productId, $variationId, $availability, $price);
                    break;
                case 'remove':
                    // If no parameter is set, remove both - used when removing watchdog from product page
                    if ($request->get('price') === null && $request->get('availability') === null) {
                        $availability = true;
                        $price = true;
                    }
                    $this->watchdog->dropWatchdog((int) $userId, $productId, $variationId, $availability, (bool) $price);
                    break;
            }
        }

        if (isAjax()) {
            return new JsonResponse(
                [
                    'success' => true,
                    'error' => null,
                ]
            );
        }

        return new RedirectResponse($this->getNextUrl($request));
    }

    private function getPrice(Request $request): ?float
    {
        if ($price = $request->get('price')) {
            $price = (float) $price;
            if ($price > 0) {
                return $price;
            }
        }

        return null;
    }

    private function getAvailability(Request $request): bool
    {
        $availability = (int) $request->get('availability', 1);
        if ($availability === 0) {
            return false;
        }

        return true;
    }

    private function getProductId(Request $request): ?int
    {
        if (!($productId = $request->get('id_product'))) {
            // backward compatibility
            if (!($productId = $request->get('IDp'))) {
                if (!($productId = $request->get('id'))) {
                    return null;
                }
            }
        }

        return (int) $productId;
    }

    private function getVariationId(Request $request): ?int
    {
        if (!($variationId = $request->get('id_variation'))) {
            // backward compatibility
            if (!($variationId = $request->get('IDv'))) {
                return null;
            }
        }

        return (int) $variationId;
    }

    private function doCheck(Request $request, $email): ?Response
    {
        if (!findModule(\Modules::WATCHDOG)) {
            throw new NotFoundHttpException('Module not found');
        }

        if (!\User::getCurrentUser()) {
            if (empty($email)) {
                return new RedirectResponse(
                    createScriptURL(
                        [
                            'URL' => 'launch.php',
                            's' => 'login',
                            'msg' => '1',
                            'url' => urlencode($GLOBALS['ctrl']['currUrl']['Abs']),
                            'ESCAPE' => 'NO',
                        ]
                    )
                );
            }

            if (!$this->emailCheck->isEmailDomainValid($email)) {
                if (isAjax()) {
                    return new JsonResponse([
                        'success' => false,
                        'error' => translate('invalidEmail', 'watchdog'),
                    ]);
                }

                $this->addErrorMessage(translate('invalidEmail', 'watchdog'));

                return new RedirectResponse($this->getNextUrl($request));
            }

            try {
                Captcha::checkCaptcha(null, 'shared');
            } catch (ValidationException $e) {
                if (isAjax()) {
                    return new JsonResponse([
                        'success' => false,
                        'error' => $e->getMessage(),
                    ]);
                }

                $this->addErrorMessage($e->getMessage());

                return new RedirectResponse($this->getNextUrl($request));
            }
        }

        return null;
    }

    private function getNextUrl(Request $request)
    {
        if ($next = $request->query->get('NEXT')) {
            return $next;
        }

        return $request->headers->get('referer', '/');
    }
}
