<?php

namespace App\Dto\Input;

use ApiPlatform\Metadata\ApiProperty;
use App\Dto\Output\OrganizationalUnitOutput;
use App\Dto\Output\RemoteCalendarOutput;
use App\Entity\OrganizationalUnit;
use App\Validator\Constraints\OrganizationalUnitMulticastMode;
use App\Validator\Constraints\OrganizationalUnitMulticastPort;
use App\Validator\Constraints\OrganizationalUnitP2PMode;
use App\Validator\Constraints\OrganizationalUnitParent;
use App\Validator\Constraints\OrganizationalUnitType;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;

#[OrganizationalUnitParent]
class OrganizationalUnitInput
{
    #[Assert\NotBlank(message: 'validators.organizational_unit.name.not_blank')]
    #[Groups(['organizational-unit:write'])]
    public ?string $name = null;

    #[Groups(['organizational-unit:write'])]
    public ?OrganizationalUnitOutput $parent = null;

    #[Groups(['organizational-unit:write'])]
    public ?string $description = null;

    #[Groups(['organizational-unit:write'])]
    public ?string $location = null;

    #[Groups(['organizational-unit:write'])]
    public ?bool $projector = null;

    #[Groups(['organizational-unit:write'])]
    public ?bool $board = null;

    #[Assert\GreaterThan(0)]
    #[Groups(['organizational-unit:write'])]
    public ?int $capacity = null;

    #[Groups(['organizational-unit:write'])]
    public ?string $comments = null;

    #[Groups(['organizational-unit:write'])]
    #[OrganizationalUnitType]
    public ?string $type = null;

    #[Groups(['organizational-unit:write'])]
    #[Assert\Valid()]
    public ?NetworkSettingsInput $networkSettings = null;

    #[Groups(['organizational-unit:write'])]
    public ?RemoteCalendarOutput $remoteCalendar = null;

    #[Groups(['organizational-unit:write'])]
    public ?bool $remotePc = false;

    #[Groups(['organizational-unit:write'])]
    public ?bool $excludeParentChanges = null;

    public function __construct(?OrganizationalUnit $organizationalUnit = null)
    {
        if (!$organizationalUnit) {
            return;
        }

        $this->name = $organizationalUnit->getName();
        if ($organizationalUnit->getParent()) {
            $this->parent = new OrganizationalUnitOutput($organizationalUnit->getParent());
        }
        $this->description = $organizationalUnit->getDescription();
        $this->location = $organizationalUnit->getLocation();
        $this->projector = $organizationalUnit->isProjector();
        $this->board = $organizationalUnit->isBoard();
        $this->capacity = $organizationalUnit->getCapacity();
        $this->comments = $organizationalUnit->getComments();
        $this->type = $organizationalUnit->getType();
        $this->remotePc = $organizationalUnit->isRemotePc();
        if ($organizationalUnit->getNetworkSettings()){
            $this->networkSettings = new NetworkSettingsInput($organizationalUnit->getNetworkSettings());
        }

        if ($organizationalUnit->getRemoteCalendar()) {
            $this->remoteCalendar = new RemoteCalendarOutput($organizationalUnit->getRemoteCalendar());
        }
    }

    public function createOrUpdateEntity(?OrganizationalUnit $organizationalUnit = null): OrganizationalUnit
    {
        if (!$organizationalUnit) {
            $organizationalUnit = new OrganizationalUnit();
        }

        $organizationalUnit->setName($this->name);
        if ($this->parent) {
            $organizationalUnit->setParent($this->parent->getEntity());
        }
        $organizationalUnit->setDescription($this->description);
        $organizationalUnit->setLocation($this->location);
        $organizationalUnit->setProjector($this->projector);
        $organizationalUnit->setBoard($this->board);
        $organizationalUnit->setCapacity($this->capacity);
        $organizationalUnit->setComments($this->comments);
        $organizationalUnit->setType($this->type);
        $organizationalUnit->setRemotePc($this->remotePc);
        $organizationalUnit->setExcludeParentChanges($this->excludeParentChanges);

        if ($this->networkSettings){
            $organizationalUnit->setNetworkSettings($this->networkSettings->createOrUpdateEntity($organizationalUnit->getNetworkSettings()));
        }

        if ($this->remoteCalendar) {
            $organizationalUnit->setRemoteCalendar($this->remoteCalendar->getEntity());
        }

        return $organizationalUnit;
    }
}