<?php

namespace KupShop\IncomakerBundle\Util\XMLElements;

use KupShop\CatalogBundle\Section\SectionTree;
use KupShop\KupShopBundle\Context\LanguageContext;
use Query\QueryBuilder;

class CategoryXMLElement implements XMLElementInterface
{
    /** @var \XMLWriter */
    protected $xmlWriter;

    /** @var QueryBuilder */
    protected $qb;

    protected $totalCount = 0;

    /** @var SectionTree */
    protected $sectionTree;

    /** @var LanguageContext */
    protected $languageContext;

    protected $languageID;

    public function __construct(SectionTree $sectionTree, LanguageContext $languageContext)
    {
        $this->sectionTree = $sectionTree;
        $this->languageContext = $languageContext;
        $this->languageID = $this->languageContext->getDefaultId();
    }

    public function getXMLOutput($specs = null): string
    {
        $this->createQB($specs);
        $this->createRootElement();
        $sections = $this->qb->execute()->fetchAll();
        if (count($sections) == $this->totalCount) {
            foreach ($this->sectionTree->getTree($this->languageID) as $section) {
                $this->createXmlElement($section);
            }
        } else {
            foreach ($sections as $section) {
                if ($section = $this->sectionTree->getSectionById($section['id'], $this->languageID)) {
                    $this->createXmlElement($section, false);
                }
            }
        }
        $this->xmlWriter->endElement();
        $this->xmlWriter->endDocument();

        return $this->xmlWriter->outputMemory();
    }

    protected function createQB($specs = null): QueryBuilder
    {
        $this->qb = sqlQueryBuilder()->select('id')->from('sections', 's')->where('id != 0');

        if ($specs) {
            $this->qb->andWhere($specs);
        }

        $this->totalCount = sqlQueryBuilder()->select('COUNT(*)')->from('sections')->where('id != 0')->execute()->fetchColumn();

        return $this->qb;
    }

    protected function createRootElement(): \XMLWriter
    {
        $this->xmlWriter = new \XMLWriter();
        $this->xmlWriter->openMemory();
        $this->xmlWriter->setIndent(true);
        $this->xmlWriter->startDocument('1.0', 'UTF-8');
        $this->xmlWriter->startElement('categories');
        $this->xmlWriter->writeAttribute('version', '2.11');
        $this->xmlWriter->writeAttribute('totalItems', $this->totalCount);

        return $this->xmlWriter;
    }

    protected function createXmlElement($section, $children = true)
    {
        $section_lang = [];
        foreach ($this->languageContext->getSupported() as $languageID => $language) {
            if ($section_l = $this->sectionTree->getSectionById($section->getId(), $languageID)) {
                $section_lang[$languageID] = $section_l;
            }
        }
        $this->xmlWriter->startElement('c');
        $this->xmlWriter->writeAttribute('id', $section->getId());
        $this->xmlWriter->writeElement('parentCategoryId', $section->getParent() ? $section->getParent()->getId() : 0);
        $this->xmlWriter->startElement('languages');
        foreach ($section_lang as $languageID => $section_l) {
            $this->xmlWriter->startElement('l');
            $this->xmlWriter->writeAttribute('lang', $languageID);
            $this->xmlWriter->writeElement('name', $section_l->getName());
            $this->xmlWriter->writeElement('url', $section_l->getFullUrl());
            $this->xmlWriter->endElement(); // l
        }
        $this->xmlWriter->endElement(); // languages
        $this->xmlWriter->endElement(); // c
        if ($children) {
            foreach ($section->getChildren() as $child) {
                $this->createXmlElement($child);
            }
        }
    }
}
