<?php
/**
 * 2007-2021 PrestaShop
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
 * versions in the future. If you wish to customize PrestaShop for your
 * needs please refer to http://www.prestashop.com for more information.
 *
 * @author    PrestaShop SA <contact@prestashop.com>
 * @copyright 2007-2021 PrestaShop SA
 * @license   http://opensource.org/licenses/afl-3.0.php  Academic Free License
 *            (AFL 3.0) International Registered Trademark & Property of
 *            PrestaShop SA
 */

namespace Prestashop\Module\AddonPayments\_3DSecure\V2;

use Address;
use Carrier;
use Cart;
use ComerciaGlobalPayments\AddonPayments\SDK\_3DSecure\v2\Enum\ShippingMethodEnum;

/**
 * Get shipping address is the same as billing.
 */
class ShippingMethod
{
    /**
     * @var \Cart
     */
    private $cart;

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

    public function __invoke()
    {
        $products = $this->cart->getProducts();
        $hasVirtualProducts = false;

        // @TODO: Add logic to discriminate between digital goods types: vouchers, subscriptions, tickets, games.
        foreach ($products as $product) {
            if ($product['is_virtual']) {
                $hasVirtualProducts = true;
                break;
            }
        }

        if ($hasVirtualProducts) {
            return (string) new ShippingMethodEnum(ShippingMethodEnum::DIGITAL_GOODS);
        }

        if (null !== ($carrier = new Carrier($this->cart->id_carrier))
            && (false === $carrier->shipping_handling || '0' === $carrier->name)
        ) {
            return (string) new ShippingMethodEnum(ShippingMethodEnum::SHIP_TO_STORE);
        }

        if ($this->cart->id_address_invoice === $this->cart->id_address_delivery
            || $this->areInvoiceDeliveryAddressesEquals()
        ) {
            return (string) new ShippingMethodEnum(ShippingMethodEnum::BILLING_ADDRESS);
        }

        if (empty($this->cart->id_address_delivery)
            || null === ($deliveryAddress = new Address($this->cart->id_address_delivery))
        ) {
            return (string) new ShippingMethodEnum(ShippingMethodEnum::NOT_SHIPPED);
        }

        if ($deliveryAddress->id_customer === $this->cart->id_customer) {
            return (string) new ShippingMethodEnum(ShippingMethodEnum::DIFFERENT_THAN_BILLING_ADDRESS);
        }

        return (string) new ShippingMethodEnum(ShippingMethodEnum::ANOTHER_VERIFIED_ADDRESS);
    }

    private function areInvoiceDeliveryAddressesEquals(): bool
    {
        $invoiceAddress = new Address($this->cart->id_address_invoice);
        $deliveryAddress = new Address($this->cart->id_address_delivery);

        if (null === $invoiceAddress || null === $deliveryAddress) {
            return false;
        }

        return $invoiceAddress->address1 === $deliveryAddress->address1
            && $invoiceAddress->address2 === $deliveryAddress->address2
            && $invoiceAddress->city === $deliveryAddress->city
            && $invoiceAddress->country === $deliveryAddress->country
            && $invoiceAddress->postcode === $deliveryAddress->postcode
            && $invoiceAddress->phone === $deliveryAddress->phone;
    }
}
