<?php

namespace PrestaShop\Module\PolarisPrestaConnector\Controller;

use PrestaShop\Module\PolarisPrestaConnector\SyncConfiguration;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use PrestaShop\Module\PolarisPrestaConnector\Syncer;
use PrestaShopBundle\Security\Annotation\AdminSecurity;

class CronAdminController extends AdminController
{
    /**
     * Autorisation maison avec un token
     * Pour la version 9.0, on désactive donc l'authentification classique et on se base uniquement sur un token de sécurité à passer dans l'URL.
     */
    protected function isAuthenticationRequired(): bool
    {
        return false;
    }

    /**
     * Point d'entrée de la tâche CRON
     * Cron action
     * 
     * @AdminSecurity("true")
     * @return JsonResponse     
     */
    public function cronAction(Request $request)
    {
        /** @var PrestaShop\Module\PolarisPrestaConnector\PolarisPrestaConnector $module */
        $module = $this->module;

        // Module est un \PrestraConnector, on le signale en PHPdoc pour avoir l'autocomplétion        
        $token_to_have = $module->getCfg()->get(SyncConfiguration::CFG_GUARD_TOKEN);
        if ($request->query->get('guard') != $token_to_have)
            return new JsonResponse(['success' => false, 'message' => 'Token de sécurité incorrect'], 403);
        
        // Fin de la session pour éviter de bloquer le processus et les autres demandes du même utilisateur
        if (session_id())
            session_write_close();

        // Initialisation du contexte prestashop
        $context = \Context::getContext();

        // Création contexte
        if (!($context->employee instanceof \Employee) || !(int) $context->employee->id) {
            // Localisation du premier employé administrateur actif
            $id_employee = \Db::getInstance()->getValue('SELECT id_employee FROM '._DB_PREFIX_.'employee WHERE active = 1 AND id_profile = 1 ORDER BY id_employee ASC');
            if ($id_employee) {
                $employee = new \Employee($id_employee);
                $context->employee = $employee;
            }
        }

        if (!($context->employee instanceof \Employee) || !(int) $context->employee->id)
            return new JsonResponse(['success' => false, 'message' => 'Aucun employé administrateur actif trouvé pour exécuter la tâche cron'], 500);

        // Le contexte admin atteint via la redirection du cron n'est pas authentifié
        // (accès par token) : la devise n'est donc pas initialisée. Or l'export des
        // commandes appelle Order::getProducts() qui lit Context::getComputingPrecision()
        // (=> currency->precision). On positionne la devise par défaut, comme le ferait
        // un contexte admin authentifié.
        if (!($context->currency instanceof \Currency) || !(int) $context->currency->id) {
            $context->currency = \Currency::getDefaultCurrency();
        }

        // Appel de la synchronisation (aucun code ici)
        $syncer = new Syncer($this->module, true);

        // Si on a passé le paramètre full à 1 dans l'URL alors on résynchronise tout
        $logs = null;
        $reason = null;
        try
        {
            // All the logs go to the symfony log system
            ob_start();

            $reason = $syncer->sync($request->query->get('full') == 1);            

            if ($request->query->get('details') == 1) $logs = ob_get_clean(); else ob_get_clean();
        }
        catch (\Exception $e)
        {
            // On affiche l'erreur
            if ($request->query->get('details') == 1) $logs = ob_get_clean(); else ob_get_clean();

            return new JsonResponse(['success' => false, 'message' => $e->getMessage()], 500);            
        }
        
        $success = $reason === null;
        $errCode = $reason ?? 'OK';
        $msg = '';
        switch ($reason ?? '') {
            case '':
                $msg = "Synchronization completed successfully.";
                break;
            case 'ALREADY_RUNNING':
                $msg = "Synchronization could not be started because another synchronization is already running.";
                break;
            case 'DISABLED':
                $msg = "Synchronization is disabled in the configuration.";
                break;
            default:
                $msg = "Synchronisation could not be started with unknown reason : " . $reason;
                break;
        }

        if (!$logs)
            $logs = "Logs disabled. Pass 'details=1' to get detailed logs.";

        $logs = explode("\n", trim($logs));

        return new JsonResponse(['success' => $success, 'errCode' => $errCode, 'message' => $msg, 'logs' => $logs]);
    }
}