<?php

declare(strict_types=1);

namespace App\Tests\Unit\Entity;

use App\Entity\Device;
use App\Entity\DeviceImageHistory;
use App\Entity\Image;
use App\Entity\RenderedAsset;
use App\Entity\SharedImage;
use App\Entity\Token;
use App\Entity\User;
use App\Enum\Orientation;
use App\Enum\TokenType;
use PHPUnit\Framework\TestCase;

class EntityAccessorTest extends TestCase
{
    public function test_device_image_history_accessors(): void
    {
        $user   = (new User())->setEmail('u@x.com');
        $image  = (new Image())->setUser($user)->setOriginalFilename('x.jpg')->setStoragePath('x');
        $device = (new Device())->setMac('AA:BB:CC:DD:EE:FF')->setName('Frame');

        $history = new DeviceImageHistory($device, $image);

        $this->assertNull($history->getId());
        $this->assertSame($device, $history->getDevice());
        $this->assertSame($image, $history->getImage());
        $this->assertInstanceOf(\DateTimeImmutable::class, $history->getServedAt());
    }

    public function test_rendered_asset_getId_setGetImage_setGetRenderedAt(): void
    {
        $asset = new RenderedAsset();
        $this->assertNull($asset->getId());

        $user  = (new User())->setEmail('u@x.com');
        $image = (new Image())->setUser($user)->setOriginalFilename('x.jpg')->setStoragePath('x');
        $asset->setImage($image);
        $this->assertSame($image, $asset->getImage());

        $this->assertNull($asset->getRenderedAt());
        $dt = new \DateTimeImmutable('2025-01-01');
        $asset->setRenderedAt($dt);
        $this->assertSame($dt, $asset->getRenderedAt());
    }

    public function test_shared_image_getSharedBy_getSharedAt(): void
    {
        $sender    = (new User())->setEmail('sender@x.com');
        $recipient = (new User())->setEmail('recip@x.com');
        $image     = (new Image())->setUser($sender)->setOriginalFilename('x.jpg')->setStoragePath('x');
        $shared    = new SharedImage($image, $recipient, $sender);

        $this->assertSame($sender, $shared->getSharedBy());
        $this->assertInstanceOf(\DateTimeImmutable::class, $shared->getSharedAt());
    }

    public function test_token_getRecipientUser_getRecipientEmail_getExpiresAt_getUsedAt(): void
    {
        $user  = (new User())->setEmail('u@x.com');
        $image = (new Image())->setUser($user)->setOriginalFilename('x.jpg')->setStoragePath('x');
        $token = new Token(TokenType::ShareApprove, $image, $user, 'recip@x.com', 7);

        $this->assertSame($user, $token->getRecipientUser());
        $this->assertSame('recip@x.com', $token->getRecipientEmail());
        $this->assertInstanceOf(\DateTimeImmutable::class, $token->getExpiresAt());
        $this->assertNull($token->getUsedAt());
        $this->assertTrue($token->isValid());
    }

    public function test_user_setRoles_getRoles_getTheme_getTimezone_eraseCredentials_collections(): void
    {
        $user = new User();

        $this->assertCount(0, $user->getDevices());
        $this->assertCount(0, $user->getImages());

        $roles = $user->getRoles();
        $this->assertContains('ROLE_USER', $roles);

        $user->setRoles(['ROLE_ADMIN']);
        $this->assertContains('ROLE_ADMIN', $user->getRoles());
        $this->assertContains('ROLE_USER', $user->getRoles());

        $this->assertNull($user->getTheme());
        $this->assertSame('UTC', $user->getTimezone());

        $user->setPassword('secret');
        $user->eraseCredentials();
        $this->assertSame('secret', $user->getPassword());
    }

    public function test_orientation_isPortrait(): void
    {
        $this->assertTrue(Orientation::Portrait->isPortrait());
        $this->assertFalse(Orientation::Landscape->isPortrait());
    }
}
