<?php

namespace Dalten\RuianToUir\Converter;

use Dalten\RuianToUir\Converter\Exception\InvalidRuianDataException;
use Dalten\RuianToUir\Converter\Field\PointCoordinatesConverter;
use Dalten\RuianToUir\Converter\Result\AddRecord;
use Dalten\RuianToUir\Converter\Result\ResultInterface;

/**
 * Převaděč na entitu městské části.
 */
class CityPart extends AbstractConverter implements ConverterInterface
{
    /**
     * Nastavuje konfiguraci třídy.
     *
     * @param PointCoordinatesConverter $coordinateConverter
     */
    public function __construct(PointCoordinatesConverter $coordinateConverter)
    {
        parent::__construct($coordinateConverter);
        $this->handledTag = 'vf:Momc';
    }

    /**
     * Převádí informace z prvku pod kurzorem do formátu UIR.
     *
     * Protože RUIAN vkládá elementy části obce do sebe, zkusí tato třída zda daný prvek neobsahuje další podobný.
     * Pokud ano, pak zpracuje až vnitřní prvek. Bohužel je toto při přáci s XMLReaderem nutnost.
     *
     * @param \XMLReader $document instance readeru s kurzorem na testovaném prvku
     *
     * @return ResultInterface pole s daty ve formátu UIR
     */
    public function convert(\XMLReader $document): ResultInterface
    {
        $data = ['stav' => 1];

        $element = $this->getNextElement($document);

        if ($element instanceof \XMLReader && $element->name === $this->handledTag) {
            // pokud jsme narazili na tag mčásti, který obsahuje další mčást, zpracujeme tu a tuhle přeskočíme
            $this->getNextElement($document);
        }

        do {
            switch ($document->name) {
                case 'mci:Kod':
                    $data['mcast_kod'] = (int) $document->readString();

                    break;
                case 'mci:Nazev':
                    $data['zkratka'] = $data['nazev'] = (string) $document->readString();

                    break;
                case 'mci:Obec':
                    if (!$document->isEmptyElement) {
                        $this->getNextElement($document);
                        if ('obi:Kod' === $document->name) {
                            $data['obec_kod'] = (int) $document->readString();
                        }
                    }

                    break;
                case 'mci:SpravniObvod':
                    if (!$document->isEmptyElement) {
                        $this->getNextElement($document);
                        if ('spi:Kod' === $document->name) {
                            $data['sobvod_kod'] = (int) $document->readString();
                        }
                    }

                    break;
                case 'mci:Mop':
                    if (!$document->isEmptyElement) {
                        $this->getNextElement($document);
                        if ('mpi:Kod' === $document->name) {
                            $data['pobvod_kod'] = (int) $document->readString();
                        }
                    }

                    break;
                case 'mci:Geometrie':
                    if (!$document->isEmptyElement) {
                        $data['geom'] = $this->getGeometryData($document);
                    }

                    break;
                default:
                    $this->skipToElementEnd($document);

                    break;
            }
        } while ($this->getNextElement($document));

        if (empty($data['mcast_kod'])) {
            throw InvalidRuianDataException::becauseRequiredAttributeIsMissing($this->getName(), 'mci:Kod');
        }

        return new AddRecord($this->getName(), $data['mcast_kod'], $data);
    }
}
