<?php

namespace Prestashop\Module\AddonPayments\Helpers;

use Address;
use Carrier;
use Cart;
use Context;
use Country;
use Brick\PhoneNumber\PhoneNumber;
use Product;
use Tools;

/**
 * BNPLHelper
 *
 * @SuppressWarnings(PHPMD.StaticAccess)
 */
class BNPLHelper
{

    /**
     * @var Context $context
     */
    public $context;

    /**
     * Return customer billing address
     *
     * @return array
     */
    public function getBillingAddress(): array
    {
        $idAddress = $this->getContext()->cart->id_address_invoice;

        return $this->getCustomerAddress($idAddress);
    }

    /**
     * Return customer shipping address.
     *
     * @param Carrier $carrier
     *
     * @return array
     * @throws \Brick\PhoneNumber\PhoneNumberParseException
     * @throws \PrestaShopDatabaseException
     * @throws \PrestaShopException
     */
    public function getShippingAddress(Carrier $carrier): array
    {
        $idAddress = $this->getContext()->cart->id_address_delivery;
        $address = $this->getCustomerAddress($idAddress);
        $address['name'] = $carrier->name;

        // $address['method'] = 'home'; // Optional Parameter.

        return $address;
    }

    /**
     * Return common customer address
     *
     * @param int $addressId
     *
     * @return array
     * @throws \Brick\PhoneNumber\PhoneNumberParseException
     * @throws \PrestaShopDatabaseException
     * @throws \PrestaShopException
     */
    private function getCustomerAddress(int $addressId): array
    {
        $address = new Address($addressId);
        $idCountry = $address->id_country;
        $countryIso3 = $this->getCountryIso3($idCountry);

        return [
            'address' => [
                'city' => $address->city,
                'country' => $countryIso3,
                'postal_code' => $address->postcode,
                'street_address' => $address->address1,
                'street_address_2' => $address->address2 ?: '-',
            ],
            'company' => $address->company ?: '-',
            //'email' => $this->context->customer->email, // Optional
            'first_name' => $address->firstname,
            'last_name' => $address->lastname,
            'phone_number' => $this->getCorrectPhone($address), // Optional ¿?
        ];
    }

    /**
     * Return paysolExtendedData cart items
     *
     * @param Cart $cart
     *
     * @return array
     * @throws \PrestaShopDatabaseException
     * @throws \PrestaShopException
     */
    public function getItems(Cart $cart): array
    {
        $items = [];

        // PS 1.7
//        if (!$cart->hasProducts()) {
//            return $items;
//        }

        $products = $cart->getProducts();

        if(empty($products)) {
            return $items;
        }

        foreach ($products as $product) {
            $productObj = new Product(
                $product['id_product'],
                false,
                $this->getContext()->language->id
            );

            $items[] = [
                'article' => [
                    'category' => $productObj->is_virtual ? 'digital'
                        : 'physical',
                    'name' => $productObj->name,
                    'reference' => $productObj->reference,
                    'type' => 'product',
                    'unit_price_with_tax' => Tools::ps_round(
                        $productObj->getPrice(),
                        2
                    ),
                ],
                //'total_discount' => Tools::ps_round($product['reduction'] * (int)$product['cart_quantity'], 2),
                'total_price_with_tax' => Tools::ps_round(
                    $product['total_wt'],
                    2
                ),
                'units' => (int)$product['cart_quantity'],
                'auto_shipping' => 'true',
            ];

            // 22-09-16 - at the present time all
            // requests must have the autoshipping field set to TRUE
        }

        return $items;
    }

    /**
     * Return Carrier item for cart
     *
     * @param \Carrier $carrier
     *
     * @return array
     */
    public function getCarrierItems(\Carrier $carrier): array
    {
        $cart = $this->getContext()->cart;
        $item = [];

        if ($cart->getCarrierCost($cart->id_carrier) > 0) {
            $item[] = [
                'article' => [
                    'category' => 'shipping_fee',
                    'name' => $carrier->name,
                    'reference' => $carrier->id,
                    'type' => 'product',
                    'unit_price_with_tax' => $cart->getCarrierCost(
                        $cart->id_carrier
                    ),
                ],
                'total_discount' => 0,
                'total_price_with_tax' => $cart->getCarrierCost(
                    $cart->id_carrier
                ),
                'units' => 1,
                'auto_shipping' => 'true',
            ];
        }

        return $item;
    }

    /**
     * Return discount item for cart
     *
     * @return array
     * @throws \Exception
     */
    public function getDiscountItems(): array
    {
        $cart = $this->getContext()->cart;
        $item = [];
        $totalDiscount = $cart->getOrderTotal(true, \Cart::ONLY_DISCOUNTS);

        if (!empty($totalDiscount)) {

            $item[] = [
                'article' => [
                    'category' => 'discount',
                    'name' => "Total discount",
                    'reference' => $cart->id."-discount",
                    'type' => 'product',
                    'unit_price_with_tax' => -\Tools::ps_round(
                        $totalDiscount,
                        2
                    ),
                ],
                'total_price_with_tax' => -\Tools::ps_round($totalDiscount, 2),
                'units' => 1,
                'auto_shipping' => 'true',
            ];
        }

        return $item;
    }

    /**
     * Return phone with prefix
     *
     * @throws \PrestaShopDatabaseException
     * @throws \PrestaShopException
     * @throws \Brick\PhoneNumber\PhoneNumberParseException
     */
    public function getCorrectPhone($address): string
    {
        if (!$address->phone) {
            return urlencode('+34600000000');
        }

        $country = new Country($address->id_country);
        $phoneNumber = PhoneNumber::parse(
            $address->phone,
            $country->iso_code
        );

        return urlencode((string)$phoneNumber);
    }

    /**
     * Return iso code alpha 3
     *
     * @param int $idCountry
     *
     * @return string
     */
    public function getCountryIso3(int $idCountry): string
    {
        $isoCode = Country::getIsoById($idCountry);

        $country_isos = json_decode(
            file_get_contents("http://country.io/iso3.json"),
            true
        );

        return $country_isos[$isoCode];
    }

    /**
     * Return PS Context
     *
     * @return Context
     */
    protected function getContext(): Context
    {
        return $this->context ?? Context::getContext();
    }

}
