<?php

namespace DMD\LaLigaApi\Dto;

use DMD\LaLigaApi\Entity\Season;
use DMD\LaLigaApi\Entity\Team;
use DMD\LaLigaApi\Exception\ValidationException;

class SeasonDto
{
    public int $id;
    public \DateTime $dateStart;
    public \DateTime $createdAt;
    public array $teamDtoList;
    public array $facilityDtoList;
    public int $leagueId;
    public int $seasonNumber;
    public int $gamesPerWeek;
    public string $leagueName;
    public int $pointsPerWin;
    public int $pointsPerLoss;
    public int $pointsPerDraw;
    public array $gameDtoList;
    public array $seasonDataDtoList;
    public bool $active;
    public array $validationErrors;
    public int $matchesBetweenTeams;

    public function createSeasonArray(): array
    {
        return [
            'id' => $this->id ?? null,
            'seasonNumber' => $this->seasonNumber ?? null,
            'gamesPerWeek' => $this->gamesPerWeek ?? null,
            'dateStart' => !empty($this->dateStart) ? $this->dateStart->format('Y-m'): null,
            'leagueId' => $this->leagueId ?? null,
            'leagueName' => $this->leagueName ?? null,
            'pointsPerWin' => $this->pointsPerWin ?? null,
            'pointsPerDraw' => $this->pointsPerDraw ?? null,
            'pointsPerLoss' => $this->pointsPerLoss ?? null,
            'active' => $this->active ?? null
        ];
    }

    public function fillFromArray(array $dataList): void
    {
        if (isset($dataList['id']))
        {
            $this->id = (int) $dataList['id'];
        }
        if (!empty($dataList['dateStart']))
        {
            $dateStart = \DateTime::createFromFormat('Y-m', $dataList['dateStart']);
             if ($dateStart)
             {
                 $this->dateStart = $dateStart;
             }
        }
        if (isset($dataList['gamesPerWeek']))
        {
            $this->gamesPerWeek = (int) $dataList['gamesPerWeek'];
        }
        if (isset($dataList['pointsPerWin']))
        {
            $this->pointsPerWin = (int) $dataList['pointsPerWin'];
        }
        if (isset($dataList['pointsPerDraw']))
        {
            $this->pointsPerDraw = (int) $dataList['pointsPerDraw'];
        }
        if (isset($dataList['pointsPerLoss']))
        {
            $this->pointsPerLoss = (int) $dataList['pointsPerLoss'];
        }
        if (isset($dataList['active']))
        {
            $this->active = $dataList['active'];
        }
        if (isset($dataList['teamList']))
        {
            foreach ($dataList['teamList'] as $teamName)
            {
                $teamDto = new TeamDto();
                $teamDto->name  = $teamName;
                $this->teamDtoList[] = $teamDto;
            }
        }
        if (!empty($dataList['facilityList']))
        {
            foreach ($dataList['facilityList'] as $facilityItem)
            {
                $facilityDto = new FacilityDto();
                $facilityDto->fillFromArray($facilityItem);
                $this->facilityDtoList[] = $facilityDto;
            }
        }
        if (isset($dataList['gameList']))
        {
            foreach ($dataList['gameList'] as $gameItem)
            {
                $gameDto = new GameDto();
                $gameDto->fillFromArray($gameItem);
                $this->gameDtoList[] = $gameDto;
            }
        }
    }

    public function fillFromEntity(Season $seasonEntity): void
    {
        if ($seasonEntity->getId() !== null)
        {
            $this->id = $seasonEntity->getId();
        }
        if ($seasonEntity->getDateStart() !== null)
        {
            $this->dateStart = $seasonEntity->getDateStart();
        }
        $leagueObj = $seasonEntity->getLeague();
        if ($leagueObj !== null)
        {
            $this->leagueId = $leagueObj->getId();
        }
        if ($seasonEntity->isActive() !== null)
        {
            $this->active = $seasonEntity->isActive();
        }
        if ($seasonEntity->getTeams())
        {
            foreach ($seasonEntity->getTeams() as $teamEntity)
            {
                $teamDto = new TeamDto();
                $teamDto->fillFromEntity($teamEntity);
                $this->teamDtoList[] = $teamDto;
            }
        }
        if ($seasonEntity->getFacilities())
        {
            foreach ($seasonEntity->getFacilities() as $facilityEntity)
            {
                $facilityDto = new FacilityDto();
                $facilityDto->fillFromEntity($facilityEntity);
                $this->facilityDtoList[] = $facilityDto;
            }
        }
        if ($seasonEntity->getGames())
        {
            foreach ($seasonEntity->getGames() as $gameEntity)
            {
                $gameDto = new GameDto();
                $gameDto->fillFromObject($gameEntity);
                $this->gameDtoList[] = $gameDto;
            }
        }
        if ($seasonEntity->getCreatedAt())
        {
            $this->createdAt = \DateTime::createFromFormat('Y-m-d H:i:s', $seasonEntity->getCreatedAt()->format('Y-m-d H:i:s'));
        }
        if ($seasonEntity->getPointsPerWin())
        {
            $this->pointsPerWin = $seasonEntity->getPointsPerWin();
        }
        if ($seasonEntity->getPointsPerLoss())
        {
            $this->pointsPerLoss = $seasonEntity->getPointsPerLoss();
        }
        if ($seasonEntity->getPointsPerDraw())
        {
            $this->pointsPerDraw = $seasonEntity->getPointsPerDraw();
        }
        if ($seasonEntity->getGamesPerWeek())
        {
            $this->gamesPerWeek = $seasonEntity->getGamesPerWeek();
        }
    }

    /**
     * @throws ValidationException
     */
    public function validate(): void
    {
        if (empty($this->pointsPerWin))
        {
            $this->validationErrors[] = 'Los puntos por partido ganado no pueden estar vacíos.';
        }
        if (
            isset($this->pointsPerDraw, $this->pointsPerWin, $this->pointsPerLoss) &&
            (($this->pointsPerWin <= $this->pointsPerDraw) ||
                ($this->pointsPerWin <= $this->pointsPerLoss))
        )
        {
            $this->validationErrors[] = 'Los puntos por partido ganado deben ser superiores a los puntos por empate y por perdida.';
        }
        if (isset($this->pointsPerDraw, $this->pointsPerWin) && ($this->pointsPerDraw > $this->pointsPerWin))
        {
            $this->validationErrors[] = 'Los puntos por empate deben ser inferiores a los puntos por partido ganado.';
        }
        if (isset($this->pointsPerDraw, $this->pointsPerLoss) && ($this->pointsPerDraw < $this->pointsPerLoss))
        {
            $this->validationErrors[] = 'Los puntos por empate deben ser superiores a los puntos por partido perdido.';
        }
        if (isset($this->pointsPerDraw, $this->pointsPerWin, $this->pointsPerLoss) && ($this->pointsPerWin + $this->pointsPerDraw + $this->pointsPerLoss > 20))
        {
            $this->validationErrors[] = 'La suma de los puntos por partidos ganados, perdidos y empatados no puede ser superior a 20.';
        }
        if (!empty($this->validationErrors))
        {
            throw new ValidationException($this->validationErrors);
        }
    }
}