<?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\Dto;

use App\Entity\PlayedGame;

/**
 * Class BattleShareDto
 *
 * @package  App\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. 20.
 */
final readonly class BattleShareDto
{
    public function __construct(
        public PlayedGame $game,
        public string     $redName,
        public string     $blueName,
        public ?int       $redPts,
        public ?int       $bluePts,
        public ?string    $resign,
        public ?string    $redAvatar,
        public ?string    $blueAvatar,
        public float      $redBonusPoints,
        public float      $blueBonusPoints,
        public array      $redBonusStats,
        public array      $blueBonusStats,
        public string     $ogTitle,
        public string     $ogDesc,
    ) {
    }

    public static function fromPlayedGame(PlayedGame $game): self
    {
        $redName = $game->red?->getUsername() ?? ($game->redAnon !== null ? 'Anonymous' : 'Guest');
        $blueName = $game->blue?->getUsername() ?? ($game->blueAnon !== null ? 'Anonymous' : 'Guest');
        $redPts = $game->redPoints;
        $bluePts = $game->bluePoints;
        $resign = $game->resign;

        $summary = self::buildSummary($redName, $blueName, $redPts, $bluePts, $resign);

        return new self(
            game: $game,
            redName: $redName,
            blueName: $blueName,
            redPts: $redPts,
            bluePts: $bluePts,
            resign: $resign,
            redAvatar: $game->red?->avatarPath,
            blueAvatar: $game->blue?->avatarPath,
            redBonusPoints: (float)($game->redBonusPoints ?? 0),
            blueBonusPoints: (float)($game->blueBonusPoints ?? 0),
            redBonusStats: $game->redBonusStats ?? [],
            blueBonusStats: $game->blueBonusStats ?? [],
            ogTitle: "MineSeeker · $summary",
            ogDesc: "Watch the battle replay: $summary — played on MineSeeker, the multiplayer minesweeper.",
        );
    }

    private static function buildSummary(
        string  $redName,
        string  $blueName,
        ?int    $redPts,
        ?int    $bluePts,
        ?string $resign,
    ): string {
        if ($resign === 'red') {
            return "$redName resigned — $blueName wins";
        }

        if ($resign === 'blue') {
            return "$blueName resigned — $redName wins";
        }

        if ($redPts !== null && $bluePts !== null) {
            if ($redPts > $bluePts) {
                return "$redName defeated $blueName ($redPts – $bluePts)";
            }
            if ($bluePts > $redPts) {
                return "$blueName defeated $redName ($bluePts – $redPts)";
            }
            return "$redName and $blueName drew ($redPts – $bluePts)";
        }

        return "$redName vs $blueName";
    }

    public function toTemplateContext(): array
    {
        return get_object_vars($this);
    }
}
