<?php

declare(strict_types=1);

/**
 * Created by Aurélien RICHAUD (01/08/2019 12:16).
 */
require_once __DIR__ . \DIRECTORY_SEPARATOR . 'ApiFrontController.php';
require_once __DIR__
    . \DIRECTORY_SEPARATOR . '..'
    . \DIRECTORY_SEPARATOR . '..'
    . \DIRECTORY_SEPARATOR . 'classes'
    . \DIRECTORY_SEPARATOR . 'Clinique.php';
require_once __DIR__
    . \DIRECTORY_SEPARATOR . '..'
    . \DIRECTORY_SEPARATOR . '..'
    . \DIRECTORY_SEPARATOR . 'classes'
    . \DIRECTORY_SEPARATOR . 'CustomerPush.php';
require_once __DIR__
    . \DIRECTORY_SEPARATOR . '..'
    . \DIRECTORY_SEPARATOR . '..'
    . \DIRECTORY_SEPARATOR . 'classes'
    . \DIRECTORY_SEPARATOR . 'OAuthAccessToken.php';

class MyvetshopcliniqueHomeModuleFrontController extends ApiFrontController
{
    /**
     * @return array<int, array{id_category: int, name: string, url: string}>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function getCatChildren(Category $cat): array
    {
        \assert(null !== $this->context);

        $ret = [];

        $catChildren = $cat->getChildrenWs();

        if (!\is_array($catChildren)) {
            $catChildren = [];
        }

        foreach ($catChildren as $row) {
            $subcat = new Category($row['id'], $this->context->language->id);

            \assert(\is_string($subcat->name));

            $ret[] = [
                'id_category' => (int) $subcat->id,
                'name' => $subcat->name,
                'url' => $subcat->getLink(),
            ];
        }

        return $ret;
    }

    /**
     * @return array<mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionConnect(): array
    {
        $context = Context::getContext();
        \assert(null !== $context);

        $accessTokenRaw = Tools::getValue('access_token');
        $accessToken = OAuthAccessToken::getByToken(\is_string($accessTokenRaw) ? $accessTokenRaw : '');

        if (!$accessToken) {
            \header('HTTP/1.0 403 Forbidden');

            return [];
        }

        if ($accessToken->id_customer != $context->customer->id) {
            \header('HTTP/1.0 403 Forbidden');

            return [];
        }

        // Indique la date de dernière utilisation
        $accessToken->last_used = \time();
        // Repousse l'expiration du token
        $accessToken->expires = \time() + 365 * 24 * 60 * 60; // 1 an
        $accessToken->update();

        $pushId = Tools::getValue('push_id');
        $pushType = Tools::getValue('push_type');

        if (\is_string($pushId) && \is_string($pushType) && $pushId && $pushType) {
            $idCustomerPush = CustomerPush::getByPushId($pushId);
            if (!$idCustomerPush) {
                $customerPush = new CustomerPush();
                $customerPush->push_id = $pushId;
                $customerPush->push_type = $pushType;
                $customerPush->id_customer = $this->context->customer->id;
                $customerPush->is_commande = true;
                $customerPush->is_clinique = true;
                // Indique quel AccessToken est utilisé

                $customerPush->id_oauth_access_token = (int) $accessToken->id;

                $customerPush->save();
            } else {
                $customerPush = new CustomerPush($idCustomerPush);
            }

            if (!$customerPush->id_oauth_access_token) {
                $customerPush->id_oauth_access_token = (int) $accessToken->id;
                $customerPush->save();
            }
        }

        return [];
    }

    /**
     * @return array<array<string|mixed>>
     *
     * @throws PrestaShopDatabaseException
     */
    protected function actionSlider(): array
    {
        $context = Context::getContext();

        \assert(null !== $context);

        $result = Db::getInstance(false)
            ->executeS(
                'SELECT `h`.`id_homeslider_slides`, `hs`.`position`, `hsl`.`title`, `hsl`.`legend`, `hsl`.`url`, `hsl`.`image`'
                . ' FROM `' . _DB_PREFIX_ . 'homeslider` h'
                . ' INNER JOIN `' . _DB_PREFIX_ . 'homeslider_slides` hs ON `hs`.`id_homeslider_slides` = `h`.`id_homeslider_slides`'
                . ' INNER JOIN `' . _DB_PREFIX_ . 'homeslider_slides_lang` hsl ON `hsl`.`id_homeslider_slides` = `hs`.`id_homeslider_slides`'
                . ' WHERE `h`.`id_shop` = 1 AND `hsl`.`id_lang` = 1 AND `hs`.`active` = 1'
                . ' ORDER BY `hs`.`position` ASC'
            );

        if (!is_array($result)) {
            $result = [];
        }

        return array_map(
            function ($row) use ($context) {
                if (!$row || !isset($row['image'])) {
                    return $row;
                }

                $row['image'] = $context->link->getMediaLink(_MODULE_DIR_ . 'ps_imageslider/images/' . $row['image']);

                return $row;
            },
            $result
        );
    }

    /**
     * @return array<int,array<string, mixed>>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionCategories(): array
    {
        $cats = \array_filter(
            \explode(',', \strval(Configuration::get('MOD_BLOCKTOPMENU_ITEMS'))),
            function ($element) {
                return \is_string($element) && 0 === \strpos($element, 'CAT');
            }
        );
        $cats = \array_map(
            function ($element) {
                return \str_replace('CAT', '', $element);
            }, $cats
        );

        $ret = [];
        foreach ($cats as $catId) {
            $cat = new Category((int) $catId, $this->context->language->id);

            \assert(\is_string($cat->name));

            if ($cat->checkAccess($this->context->customer->id)) {
                $ret[] = [
                    'id_category' => (int) $cat->id,
                    'name' => $cat->name,
                    'url' => $cat->getLink(),
                    'children' => $this->getCatChildren($cat),
                ];
            }
        }

        return $ret;
    }

    /**
     * @return array<string, string|bool>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionSendMessage(): array
    {
        $context = Context::getContext();
        \assert(null !== $context);

        $typeContact = Tools::getValue('contact');
        $nom = Tools::getValue('nom');
        $prenom = Tools::getValue('prenom');
        $email = Tools::getValue('email');
        $message = Tools::getValue('message');

        if (
            !\is_string($typeContact)
            || !\is_string($nom)
            || !\is_string($prenom)
            || !\is_string($email)
            || !\is_string($message)
            || !$typeContact
            || !$nom
            || !$prenom
            || !$email
            || !$message
            || !Validate::isEmail($email)
        ) {
            \header('HTTP/1.0 400 Bad Request');

            return ['success' => false, 'message' => 'Tous les champs doivent être remplis et valides'];
        }

        $cliniqueId = Clinique::getCliniqueIdByGroup((int) $this->context->customer->id_default_group);
        if (!$cliniqueId) {
            $clinique = null;
            $employee = null;
        }
        $clinique = new Clinique($cliniqueId);
        $employee = new Employee($clinique->id_employee);

        $emails = [];
        // $emails                  = [$employee->email => $employee->firstname . ' ' . $employee->lastname, ];

        if ('sav' == $typeContact) {
            $emails['sav@vetinweb.com'] = 'SAV VetInWeb';
        } elseif ('clinique' == $typeContact) {
            if (!$clinique->id) {
                \header('HTTP/1.0 400 Bad Request');

                return ['success' => false, 'message' => "Vous n'avez pas de clinique associée à votre compte"];
            }

            $emails[$employee->email] = $employee->firstname . ' ' . $employee->lastname;
        }

        $templateVars = [
            '{clinique_name}' => $employee->firstname . ' ' . $employee->lastname,
            '{clinique_email}' => $employee->email,
            '{nom}' => $nom,
            '{prenom}' => $prenom,
            '{email}' => $email,
            '{message}' => $message,
        ];

        foreach ($emails as $email => $name) {
            Mail::Send(
                $context->language->id,
                'client-app-contact',
                'Contact MyVetshop',
                $templateVars, /* @phpstan-ignore-line */
                $email,
                $name,
                null,
                'MyVetShop',
                null,
                null,
                _PS_MAIL_DIR_,
                false,
                null,
                null,
                $email
            );
        }

        return ['success' => true, 'message' => 'Votre message a bien été envoyé.'];
    }

    protected function actionLink(): void
    {
        $link = Tools::getValue('link');

        if (!\is_string($link)) {
            $link = '';
        }

        switch ($link) {
            case 'addresses':
                $url = (new Link())->getPageLink('addresses', true);
                break;

            case 'cards':
                $url = (new Link())->getBaseLink($this->context->shop->id, true) . 'module/myvetshoppayment/cards';
                break;

            case 'discount':
                $url = (new Link())->getPageLink('discount', true);
                break;

            case 'loyalty':
                $url = (new Link())->getBaseLink($this->context->shop->id, true) . 'module/loyaltyeditpoints/points?process=summary';
                break;

            default:
                $url = (new Link())->getBaseLink($this->context->shop->id, true);
        }

        Tools::redirect($url);
        exit;
    }

    /**
     * @return array<array<string, string>>
     */
    protected function actionMyAccountLinks(): array
    {
        $link = new Link();

        $links = [
            [
                'icon' => 'fal fa-building',
                'url' => $link->getBaseLink() . 'index.php?fc=module&module=myvetshopclinique&controller=home&action=link&link=addresses',
                'title' => 'Mes adresses',
            ],
            [
                'icon' => 'fal fa-flag',
                'url' => $link->getBaseLink() . 'index.php?fc=module&module=myvetshopclinique&controller=home&action=link&link=loyalty',
                'title' => 'Mes points fidélité',
            ],
            [
                'icon' => 'fal fa-percentage',
                'url' => $link->getBaseLink() . 'index.php?fc=module&module=myvetshopclinique&controller=home&action=link&link=discount',
                'title' => 'Mes bons de réduction',
            ],
        ];

        // Uniquement si le paiement express est activé
        if (Configuration::get('MVS_PAYMENT_PAIEMENT_EXPRESS')) {
            $links[] = [
                'icon' => 'fal fa-credit-card',
                'url' => $link->getBaseLink() . 'index.php?fc=module&module=myvetshopclinique&controller=home&action=link&link=cards',
                'title' => 'Mes CBs paiement express',
            ];
        }

        return $links;
    }

    public function run(): void
    {
        $this->init();

        $action = Tools::getValue('action', 'nothing');
        if (!\is_string($action)) {
            $action = 'nothing';
        }

        switch ($action) {
            case 'connect':
                $ret = $this->actionConnect();
                break;

            case 'slider':
                $ret = $this->actionSlider();
                break;

            case 'categories':
                $ret = $this->actionCategories();
                break;

            case 'sendMessage':
                $ret = $this->actionSendMessage();
                break;

            case 'link':
                $this->actionLink();
                $ret = null;
                break;

            case 'myAccountLinks':
                $ret = $this->actionMyAccountLinks();
                break;

            default:
                $ret = [];
        }

        echo \json_encode($ret, \JSON_PRETTY_PRINT);
    }
}
