<?php
/**
 * 2013 - 2025 Payplug SAS.
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0).
 * It is available through the world-wide-web at this URL:
 * https://opensource.org/licenses/osl-3.0.php
 * If you are unable to obtain it through the world-wide-web, please send an email
 * to contact@payplug.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade PayPlug module to newer
 * versions in the future.
 *
 * @author    Payplug SAS
 * @copyright 2013 - 2025 Payplug SAS
 * @license   https://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 *  International Registered Trademark & Property of Payplug SAS
 */

namespace PayPlug\src\actions;

if (!defined('_PS_VERSION_')) {
    exit;
}

class CartAction
{
    private $dependencies;
    private $dispatcher;
    private $plugin;
    private $configuration;
    private $context;

    public function __construct($dependencies)
    {
        $this->dependencies = $dependencies;
    }

    /**
     * @description Generic method for rendering payment
     * actions elements for the cart and product pages
     *
     * @return false|string
     */
    public function renderPaymentCTA()
    {
        $this->setParameters();
        $payment_methods = $this->configuration->getValue('payment_methods');
        $payment_methods = json_decode($payment_methods, true);
        $applepay_display = json_decode($this->configuration->getValue('applepay_display'), true);
        $is_sandbox_mode = (bool) $this->configuration->getValue('sandbox_mode');
        $controller = $this->dispatcher->getInstance()->getController();

        // Validate if Apple Pay button should be displayed
        if (
            null === $applepay_display
            || $is_sandbox_mode
            || !isset($payment_methods['applepay']) || !$payment_methods['applepay']
            || (!(bool) $applepay_display['cart'] && 'cart' === $controller)
            || (!(bool) $applepay_display['product'] && 'product' === $controller)
        ) {
            return false;
        }

        return $this->renderApplepayCheckout();
    }

    /**
     * @description Render the Apple Pay button based on cart contents and allowed carriers.
     *
     * This function checks if Apple Pay is compatible, analyzes the cart contents, and
     * compares it with the allowed carriers. If at least one common carrier is found,
     * it returns the Apple Pay button template; otherwise, it returns false. If the cart
     * contains at least one carrier with a value of 0, it returns false.
     *
     * The function handles rendering for both the cart and product pages by determining
     * the current controller and setting the workflow accordingly.
     *
     * @return false|string
     */
    public function renderApplePayCheckout()
    {
        $this->setParameters();

        // if customer is not logged and the shop is configured to refuse guest order then return false
        $guest_checkout_enabled = $this->plugin
            ->getConfigurationClass()
            ->getValue('PS_GUEST_CHECKOUT_ENABLED');
        $customer = $this->plugin
            ->getCustomer()
            ->get((int) $this->context->customer->id);
        if (!(bool) $guest_checkout_enabled && !(bool) $customer->id) {
            return false;
        }

        $browser = $this->dependencies
            ->getPlugin()
            ->getBrowser()
            ->getName();
        $isApplePayCompatible = $this->dependencies
            ->getValidators()['browser']
            ->isApplePayCompatible($browser);

        // If browser is not safari, no appelpay on cart page
        if (!$isApplePayCompatible['result']) {
            return false;
        }

        // Get Carrier list
        $carriers_list = $this->dependencies
            ->getPlugin()
            ->getPaymentMethodClass()
            ->getPaymentMethod('applepay')
            ->getCarriersList();

        $controller = $this->dispatcher
            ->getInstance()
            ->getController();
        if (empty($carriers_list) && 'product' != $controller) {
            return false;
        }
        if ('product' == $controller) {
            $id_product = (int) $this->dependencies
                ->getPlugin()
                ->getTools()
                ->tool('getValue', 'id_product');
            $has_compatible_carriers = $this->dependencies
                ->getPlugin()
                ->getPaymentMethodClass()
                ->getPaymentMethod('applepay')
                ->hasCompatibleCarriersForProduct($id_product);
            if (!$has_compatible_carriers) {
                return false;
            }
        }

        $applepay_js_url = $this->dependencies
            ->getPlugin()
            ->getRoutes()
            ->getSourceUrl()['applepay'];

        $controller = $this->dispatcher
            ->getInstance()
            ->getController();
        $applepay_workflow = 'cart' === $controller ? 'shopping-cart' : 'product';

        $this->dependencies
            ->getPlugin()
            ->getAssign()
            ->assign([
                'applepay_js_url' => $applepay_js_url,
                'applepay_workflow' => $applepay_workflow,
                'iso_lang' => $this->context->language->iso_code,
            ]);

        $this->dependencies
            ->getPlugin()
            ->getMedia()
            ->addJsDef([
                'applePayPaymentRequestAjaxURL' => $this->context->link->getModuleLink($this->dependencies->name, 'applepaypaymentrequest', [], true),
                'applePayMerchantSessionAjaxURL' => $this->context->link->getModuleLink($this->dependencies->name, 'dispatcher', [], true),
                'applePayPaymentAjaxURL' => $this->context->link->getModuleLink($this->dependencies->name, 'validation', [], true),
                'applePayIdCart' => $this->context->cart->id,
            ]);

        return $this->dependencies->configClass
            ->fetchTemplate('checkout/payment/applepay.tpl');
    }

    /**
     * @description Set needed object from dependencies
     */
    private function setParameters()
    {
        $this->plugin = $this->plugin ?: $this->dependencies
            ->getPlugin();
        $this->context = $this->context ?: $this->plugin->getContext()->get();
        $this->configuration = $this->configuration ?: $this->plugin->getConfigurationClass();
        $this->dispatcher = $this->dependencies->getPlugin()->getDispatcher();
    }
}
