<?php
/**
 * Copyright since 2025 InPost S.A.
 *
 * For the full license information, please view the LICENSE file bundled with the module.
 *
 * @author InPost S.A.
 * @copyright since 2025 InPost S.A.
 * @license MIT
 */

declare(strict_types=1);

namespace InPost\International\Controller\Front\Checkout;

use InPost\International\Checkout\Exception\InvalidPhoneNumberException;
use InPost\International\Checkout\Phone\PhoneNumberValidatorInterface;
use InPost\International\HttpFoundation\RequestHelper;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;

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

final class ValidatePhoneNumberController
{
    /**
     * @var \Context
     */
    private $context;

    /**
     * @var PhoneNumberValidatorInterface
     */
    private $validator;

    public function __construct(\Context $context, PhoneNumberValidatorInterface $validator)
    {
        $this->context = $context;
        $this->validator = $validator;
    }

    public function __invoke(Request $request): Response
    {
        $address = $this->getAddress($request);

        try {
            $this->validator->validate($address);
        } catch (InvalidPhoneNumberException $e) {
            return new JsonResponse([
                'error' => $e->getMessage(),
            ], Response::HTTP_UNPROCESSABLE_ENTITY);
        }

        return new Response();
    }

    private function getAddress(Request $request): \Address
    {
        if (!$request->request->has('address')) {
            return $this->getDeliveryAddress($this->context->cart);
        }

        $data = RequestHelper::getAll($request->request, 'address');
        $address = new \Address();

        foreach ($data as $name => $value) {
            if (!property_exists($address, $name)) {
                continue;
            }

            $address->{$name} = $value;
        }

        return $address;
    }

    private function getDeliveryAddress(\Cart $cart): \Address
    {
        if (0 >= $addressId = (int) $cart->id_address_delivery) {
            throw new ConflictHttpException('Delivery address is not selected.');
        }

        /** @var \Address[] $addresses */
        $addresses = $cart->getAddressCollection();
        if (null === $address = $addresses[$addressId] ?? null) {
            throw new \RuntimeException('Address not found.');
        }

        return $address;
    }
}
