<?php declare(strict_types=1);
/**
 * This file is part of the SplendidBear Websites' projects.
 *
 * Copyright (c) 2026 @ www.splendidbear.org
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace App\Tests\Dto;

use App\Dto\ProfileGameDto;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;

/**
 * Class ProfileGameDtoTest
 *
 * @package  App\Tests\Dto
 * @author   Lang <https://www.splendidbear.org>
 * @category Class
 * @license  https://www.gnu.org/licenses/lgpl-3.0.en.html GNU Lesser General Public License
 * @link     www.splendidbear.org
 * @since    2026. 04. 21.
 */
#[TestDox('Profile Game Dto')]
class ProfileGameDtoTest extends TestCase
{
    #[Test]
    #[TestDox('Json serialize returns all properties')]
    public function jsonSerializeReturnsAllProperties(): void
    {
        $dto = new ProfileGameDto(
            id: 1,
            uuid: '550e8400-e29b-41d4-a716-446655440000',
            redName: 'RedPlayer',
            blueName: 'BluePlayer',
            redAvatar: '/uploads/avatars/red.png',
            blueAvatar: '/uploads/avatars/blue.png',
            redPoints: 10,
            bluePoints: 8,
            redExplodedBomb: false,
            blueExplodedBomb: true,
            resign: null,
            created: '2026-04-20 10:00',
            date: '2026-04-20 10:30',
            isRed: true,
            result: 'win',
            myPoints: 10,
            oppPoints: 8,
            redBonusPoints: 5.5,
            blueBonusPoints: 2.0,
            redBonusStats: ['blindHits' => 2, 'chainBest' => 3],
            blueBonusStats: ['blindHits' => 1, 'chainBest' => 2],
            bothRegistered: true,
        );

        $json = $dto->jsonSerialize();

        $this->assertSame(1, $json['id']);
        $this->assertSame('550e8400-e29b-41d4-a716-446655440000', $json['uuid']);
        $this->assertSame('RedPlayer', $json['redName']);
        $this->assertSame('BluePlayer', $json['blueName']);
        $this->assertSame('/uploads/avatars/red.png', $json['redAvatar']);
        $this->assertSame('/uploads/avatars/blue.png', $json['blueAvatar']);
        $this->assertSame(10, $json['redPoints']);
        $this->assertSame(8, $json['bluePoints']);
        $this->assertFalse($json['redExplodedBomb']);
        $this->assertTrue($json['blueExplodedBomb']);
        $this->assertNull($json['resign']);
        $this->assertSame('2026-04-20 10:00', $json['created']);
        $this->assertSame('2026-04-20 10:30', $json['date']);
        $this->assertTrue($json['isRed']);
        $this->assertSame('win', $json['result']);
        $this->assertSame(10, $json['myPoints']);
        $this->assertSame(8, $json['oppPoints']);
        $this->assertSame(5.5, $json['redBonusPoints']);
        $this->assertSame(2.0, $json['blueBonusPoints']);
        $this->assertSame(['blindHits' => 2, 'chainBest' => 3], $json['redBonusStats']);
        $this->assertSame(['blindHits' => 1, 'chainBest' => 2], $json['blueBonusStats']);
        $this->assertTrue($json['bothRegistered']);
    }

    #[Test]
    #[TestDox('Json serialize with null values')]
    public function jsonSerializeWithNullValues(): void
    {
        $dto = new ProfileGameDto(
            id: null,
            uuid: null,
            redName: 'Guest',
            blueName: 'Guest',
            redAvatar: null,
            blueAvatar: null,
            redPoints: null,
            bluePoints: null,
            redExplodedBomb: null,
            blueExplodedBomb: null,
            resign: null,
            created: null,
            date: null,
            isRed: false,
            result: 'draw',
            myPoints: null,
            oppPoints: null,
            redBonusPoints: 0.0,
            blueBonusPoints: 0.0,
            redBonusStats: [],
            blueBonusStats: [],
            bothRegistered: false,
        );

        $json = $dto->jsonSerialize();

        $this->assertNull($json['id']);
        $this->assertNull($json['uuid']);
        $this->assertNull($json['redAvatar']);
        $this->assertNull($json['blueAvatar']);
        $this->assertNull($json['redPoints']);
        $this->assertNull($json['bluePoints']);
        $this->assertSame('draw', $json['result']);
        $this->assertFalse($json['bothRegistered']);
    }
}
