<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Marketing\Emailing;

use CpCreation\VitiCore\Cart\Repository\CartRepository;
use CpCreation\VitiCore\User\Repository\UserRepository;

final readonly class VitiCoreRecipientProvider
{
    public const string SOURCE_MARKETING_OPT_IN = 'marketing_opt_in';
    public const string SOURCE_GUEST_PURCHASERS = 'guest_purchasers';

    public function __construct(
        private UserRepository $userRepository,
        private CartRepository $cartRepository,
    ) {}

    /** @return list<array{email: string, attributes: array<string, string>}> */
    public function contacts(string $source): array
    {
        if (self::SOURCE_MARKETING_OPT_IN === $source) {
            $contacts = [];
            foreach ($this->userRepository->findMarketingOptInUsers() as $user) {
                $email = mb_strtolower(mb_trim((string) $user->getEmail()));
                if (false === filter_var($email, \FILTER_VALIDATE_EMAIL)) {
                    continue;
                }
                $address = $user->getInvoiceAddress() ?? $user->getDeliveryAddress();
                $contacts[$email] = $this->contact(
                    $email,
                    $address?->getFirstname(),
                    $address?->getLastname(),
                    self::SOURCE_MARKETING_OPT_IN,
                );
            }

            return array_values($contacts);
        }

        if (self::SOURCE_GUEST_PURCHASERS === $source) {
            $contacts = [];
            foreach ($this->cartRepository->findGuestPurchaserContacts() as $row) {
                $email = mb_strtolower(mb_trim($row['email']));
                if (false === filter_var($email, \FILTER_VALIDATE_EMAIL)) {
                    continue;
                }
                $contacts[$email] = $this->contact(
                    $email,
                    $row['firstname'],
                    $row['lastname'],
                    self::SOURCE_GUEST_PURCHASERS,
                );
            }

            return array_values($contacts);
        }

        throw new \InvalidArgumentException('La source de destinataires VitiCore est inconnue.');
    }

    /** @return array{email: string, attributes: array<string, string>} */
    private function contact(string $email, ?string $firstname, ?string $lastname, string $source): array
    {
        return [
            'email' => $email,
            'attributes' => array_filter([
                'FIRSTNAME' => null === $firstname ? null : mb_trim($firstname),
                'LASTNAME' => null === $lastname ? null : mb_trim($lastname),
                'VITICORE_SOURCE' => $source,
            ], static fn (?string $value): bool => null !== $value && '' !== $value),
        ];
    }
}
