<?php

declare(strict_types=1);

namespace MyCustomizer\WooCommerce\Connector\Controller\Admin;

use Exception;
use MyCustomizer\WooCommerce\Connector\Auth\MczrAccess;
use MyCustomizer\WooCommerce\Connector\Config\MczrConfig;
use MyCustomizer\WooCommerce\Connector\Controller\Admin\MczrProductTypeController;
use MyCustomizer\WooCommerce\Connector\Factory\MczrFactory;
use MyCustomizer\WooCommerce\Connector\Libs\MczrConnect;
use MyCustomizer\WooCommerce\Connector\Libs\MczrFlashMessage;
use MyCustomizer\WooCommerce\Connector\Libs\MczrSettings;
use MyCustomizer\WooCommerce\Connector\Service\Admin\MczrDiagnosticService;
use Symfony\Component\HttpFoundation\Request;

class MczrSettingController
{
    private $factory;
    private $flash;
    private $mczr;
    private $mczrDiagnosticService;
    private $mczrProductTypeController;
    private $request;
    private $settings;
    private $twig;

    private $tabs = [
        'layout' => 'Layout',
        'linking' => 'Linking',
        'diagnostic' => 'Diagnostic',
    ];

    public function __construct()
    {
        $this->request = Request::createFromGlobals();
        $this->factory = new MczrFactory();
        $this->twig = $this->factory->getTwig();
        $this->flash = new MczrFlashMessage();
        $this->mczr = new MczrConnect();
        $this->settings = new MczrSettings();
        $this->mczrProductTypeController = new MczrProductTypeController();
        $this->mczrDiagnosticService = new MczrDiagnosticService();
    }

    public function init(): void
    {
        \add_action('admin_menu', [$this, 'addSubmenu'], 10, 0);
    }

    public function addSubmenu(): void
    {
        \add_submenu_page('woocommerce', 'Kickflip Settings', 'Kickflip', 'manage_options', 'mczrSettings', [$this, 'settingPageAction']);
    }

    public function settingPageAction(): void
    {
        MczrAccess::can('manage_options');

        if (isset($_POST) && !empty($_POST)) {
            \check_admin_referer('mczr-settings-save');

            if (!count($_POST)) {
                $this->flash->display();
                $this->renderForm();

                return;
            }

            $section = $this->request->get('section');

            if ($section === 'layout') {
                $this->saveLayoutForm();
            } elseif ($section === 'linking') {
                $this->saveLinkingForm();
            } elseif ($section === 'diagnostic') {
                $this->flash->display();
                $this->renderForm();
                $this->runDiagnostic();

                return;
            }
        }

        $this->flash->display();
        $this->renderForm();
    }

    private function renderForm(): void
    {
        MczrAccess::can('manage_options');

        $brand = $this->settings->get('brand');

        if (empty($brand)) {
            $mczrDashboardLinkHref = MczrConfig::getConfig()['registerUrl'] . '?eCommerce=woocommerce&shop=' . \get_site_url() . '&woocommerceToken=' . $this->settings->get('authorizationKey');
            $mczrDashboardLinkTitle = '(!) Please register on Kickflip Dashboard';
        } else {
            $mczrDashboardLinkHref = str_replace('{{brand}}', $brand, MczrConfig::getConfig()['dashboardUrlPattern']);
            $mczrDashboardLinkTitle = 'Open Kickflip Dashboard';
        }

        $vars = [
            'form' => [
                'mczrDashboardLinkHref' => $mczrDashboardLinkHref,
                'mczrDashboardLinkTitle' => $mczrDashboardLinkTitle,
                'title' => \esc_html(\get_admin_page_title()),
                'iframeWidth' => $this->settings->get('iframeWidth'),
                'iframeHeight' => $this->settings->get('iframeHeight'),
                'iframeHook' => $this->settings->get('iframeHook'),
                'iframeHookPriority' => $this->settings->get('iframeHookPriority'),
                'productCss' => $this->settings->get('productCss'),
                'brand' => $brand,
                'shopId' => $this->settings->get('shopId'),
                'apiToken' => $this->settings->get(MczrConnect::TOKEN_FIELD_NAME),
                'token' => \wp_nonce_field('mczr-settings-save'),
                'diagnosticOptions' => $this->request->get('options', []),
            ],
            'tabs' => $this->tabs,
            'activeTab' => $this->getActiveTab(),
        ];

        $allowed_html = [
            'a' => [
                'href' => [],
                'target' => [],
                'class' => [],
                'onclick' => [],
            ],
            'br' => [],
            'button' => [
                'class' => [],
                'id' => [],
                'name' => [],
                'type' => [],
                'disabled' => [],
            ],
            'div' => [
                'class' => []
            ],
            'fieldset' => [],
            'form' => [
                'name' => [],
                'method' => [],
            ],
            'h1' => [],
            'h2' => [],
            'h3' => [],
            'hr' => [],
            'img' => [
                'src' => []
            ],
            'input' => [
                'id' => [],
                'class' => [],
                'name' => [],
                'placeholder' => [],
                'readonly' => [],
                'type' => [],
                'value' => [],
                'required' => [],
                'checked' => [],
            ],
            'label' => [
                'class' => [],
                'for' => [],
            ],
            'p' => [],
            'script' => [],
            'small' => [
                'class' => []
            ],
            'span' => [],
            'style' => [],
            'table' => [
                'class' => []
            ],
            'tbody' => [],
            'td' => [],
            'textarea' => [
                'class' => [],
                'id' => [],
                'help' => [],
                'name' => [],
                'rows' => [],
                'cols' => [],
            ],
            'th' => [],
            'tr' => [],
        ];

        echo \wp_kses($this->twig->render('Settings/header.html.twig', $vars), $allowed_html);
        echo \wp_kses($this->twig->render("Settings/{$vars['activeTab']}.html.twig", $vars), $allowed_html);
        if ($vars['activeTab'] === 'diagnostic') {
            echo $this->twig->render('Settings/diagnostic-validation.js.twig');
        }
    }

    private function getActiveTab(): string
    {
        if (isset($_GET['tab']) && array_key_exists($_GET['tab'], $this->tabs)) {
            return $_GET['tab'];
        }

        return 'layout';
    }

    private function saveLayoutForm(): void
    {
        $this->settings->update(
            [
                'iframeWidth' => $this->request->get('iframeWidth'),
                'iframeHeight' => $this->request->get('iframeHeight'),
                'iframeHook' => $this->request->get('iframeHook'),
                'iframeHookPriority' => $this->request->get('iframeHookPriority'),
                'productCss' => $this->request->get('productCss'),
            ]
        );

        $this->flash->add(MczrFlashMessage::TYPE_SUCCESS, sprintf('Settings are saved. '));
    }

    /**
     * @throws Exception
     */
    private function saveLinkingForm(): void
    {
        $unlinkBrand = null !== $this->request->get('unlinkBrand') && $this->request->get('unlinkBrand') == 'true';
        $syncCode = $this->request->get('syncCode');

        if (isset($syncCode) && '' != $syncCode) {
            try {
                $syncCodeDecoded = json_decode(base64_decode($syncCode));

                if (isset($syncCodeDecoded->brand) && isset($syncCodeDecoded->token) && isset($syncCodeDecoded->onlineStoreId)) {
                    $this->settings->update(
                        [
                            'brand' => $syncCodeDecoded->brand,
                            'apiToken' => $syncCodeDecoded->token,
                        ]
                    );

                    $this->mczr->connect($syncCodeDecoded->brand, $syncCodeDecoded->onlineStoreId);
                    $this->flash->add(MczrFlashMessage::TYPE_SUCCESS, sprintf('Your store is now synced with your MyCustomizer account.'));
                } elseif (
                    isset($syncCodeDecoded->startingPointId)
                    && isset($syncCodeDecoded->startingPointName)
                    && isset($syncCodeDecoded->startingPointImage)
                    && isset($syncCodeDecoded->price)
                ) {
                    $productId = $this->mczrProductTypeController->create($syncCodeDecoded->startingPointId, $syncCodeDecoded->startingPointName, $syncCodeDecoded->price);

                    $this->mczrProductTypeController->attachProductThumbnail($productId, $syncCodeDecoded->startingPointImage);

                    $this->flash->add(MczrFlashMessage::TYPE_SUCCESS, sprintf('Your product was created.'));
                } else {
                    throw new Exception('syncCode is not valid.');
                }
            } catch (Exception $err) {
                $this->flash->add(MczrFlashMessage::TYPE_ERROR, 'Sync code: the sync code you entered is not valid');
                $this->flash->display();

                return;
            }
        } else {
            $this->settings->update(
                [
                    'shopId' => $unlinkBrand ? '' : $this->request->get('shopId'),
                    'brand' => $unlinkBrand ? '' : $this->request->get('brand'),
                    'apiToken' => $unlinkBrand ? '' : $this->request->get(MczrConnect::TOKEN_FIELD_NAME),
                ]
            );

            $flashMessage = $unlinkBrand ? 'Brand Unlinked. ' : 'Settings are saved. ';
            $this->flash->add(MczrFlashMessage::TYPE_SUCCESS, sprintf($flashMessage));
        }
    }

    private function runDiagnostic(): void
    {
        $options = $this->request->get('options', []);

        $vars = [
            'results' => $this->mczrDiagnosticService->runDiagnostic($options)
        ];

        echo $this->twig->render('Settings/diagnostic-results.html.twig', $vars);
    }
}
