<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Action\User\UpdateProfile;

use Chill\MainBundle\Action\User\UpdateProfile\UpdateProfileCommand;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Notification\FlagProviders\NotificationFlagProviderInterface;
use Chill\MainBundle\Notification\NotificationFlagManager;
use libphonenumber\PhoneNumber;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Translation\TranslatableMessage;

/**
 * @internal
 *
 * @coversNothing
 */
final class UpdateProfileCommandTest extends TestCase
{
    public function testCreateTransfersPhonenumberAndNotificationFlags(): void
    {
        $user = new User();

        // set a phone number
        $phone = new PhoneNumber();
        $phone->setCountryCode(32); // Belgium
        $phone->setNationalNumber(471234567);
        $user->setPhonenumber($phone);

        // configure notification flags on the user via helpers
        $flagA = 'foo';
        $flagB = 'bar';

        // For tickets: immediate true, daily false
        $user->setNotificationImmediately($flagA, true);
        $user->setNotificationDailyDigest($flagA, false);

        // For reports: immediate false, daily true
        $user->setNotificationImmediately($flagB, false);
        $user->setNotificationDailyDigest($flagB, true);

        // a third flag not explicitly set to validate default behavior from User
        $flagC = 'foobar'; // by default immediate-email is true, daily-digest is false per User::getNotificationFlagData

        $manager = $this->createNotificationFlagManager([$flagA, $flagB, $flagC]);

        $command = UpdateProfileCommand::create($user, $manager);

        // phone number transferred
        self::assertInstanceOf(PhoneNumber::class, $command->phonenumber);
        self::assertSame($phone->getCountryCode(), $command->phonenumber->getCountryCode());
        self::assertSame($phone->getNationalNumber(), $command->phonenumber->getNationalNumber());

        // flags transferred consistently
        self::assertArrayHasKey($flagA, $command->notificationFlags);
        self::assertArrayHasKey($flagB, $command->notificationFlags);
        self::assertArrayHasKey($flagC, $command->notificationFlags);

        self::assertSame([
            'immediate_email' => true,
            'daily_digest' => false,
        ], $command->notificationFlags[$flagA]);

        self::assertSame([
            'immediate_email' => false,
            'daily_digest' => true,
        ], $command->notificationFlags[$flagB]);

        // default from User::getNotificationFlagData -> immediate true, daily false
        self::assertSame([
            'immediate_email' => true,
            'daily_digest' => false,
        ], $command->notificationFlags[$flagC]);
    }

    private function createNotificationFlagManager(array $flags): NotificationFlagManager
    {
        $providers = array_map(fn (string $flag) => new class ($flag) implements NotificationFlagProviderInterface {
            public function __construct(private readonly string $flag) {}

            public function getFlag(): string
            {
                return $this->flag;
            }

            public function getLabel(): TranslatableMessage
            {
                return new TranslatableMessage($this->flag);
            }
        }, $flags);

        return new NotificationFlagManager($providers);
    }
}
