<?php
namespace Medienreaktor\Products\Controller;

use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Http\ForwardResponse;

/***
 *
 * This file is part of the "Products" Extension for TYPO3 CMS.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 *  (c) 2017 Daniel Kestler &lt;daniel.kestler@medienreaktor&gt;, medienreaktor GmbH
 *
 ***/

/**
 * BackendController
 */
class BackendController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
    /**
     * productRepository
     *
     * @var \Medienreaktor\Products\Domain\Repository\ProductRepository
     */
    protected $productRepository = null;

    /**
     * productGroupRepository
     *
     * @var \Medienreaktor\Products\Domain\Repository\ProductGroupRepository
     */
    protected $productGroupRepository = null;

    /**
     * propertyRepository
     *
     * @var \Medienreaktor\Products\Domain\Repository\PropertyRepository
     */
    protected $propertyRepository = null;

    /**
     * propertyGroupRepository
     *
     * @var \Medienreaktor\Products\Domain\Repository\PropertyGroupRepository
     */
    protected $propertyGroupRepository = null;
    public function __construct(\Medienreaktor\Products\Domain\Repository\ProductRepository $productRepository, \Medienreaktor\Products\Domain\Repository\ProductGroupRepository $productGroupRepository, \Medienreaktor\Products\Domain\Repository\PropertyRepository $propertyRepository, \Medienreaktor\Products\Domain\Repository\PropertyGroupRepository $propertyGroupRepository)
    {
        $this->productRepository = $productRepository;
        $this->productGroupRepository = $productGroupRepository;
        $this->propertyRepository = $propertyRepository;
        $this->propertyGroupRepository = $propertyGroupRepository;
    }

    /**
     * action export
     *
     * @return void
     */
    public function exportAction(): \Psr\Http\Message\ResponseInterface
    {
        $args = $this->request->getArguments();
        $pageUid = intval($_GET['id']);
        $this->view->assign('pageUid', $pageUid);

        if ($pageUid && $pageUid > 0) {
            $productGroups = $this->productGroupRepository->findByPidRecursively($pageUid);
            $this->view->assign('productGroups', $productGroups);

            $products = $this->productRepository->findByPidRecursively($pageUid);
            $this->view->assign('products', $products);
        }
        return $this->htmlResponse();
    }


    /**
     * action downloadCSV
     *
     * @return void
     */
    public function downloadCSVAction(): \Psr\Http\Message\ResponseInterface
    {
        $GLOBALS['TSFE'] = new \stdClass();
        $GLOBALS['TSFE']->gr_list = '0,-2';

        $args = $this->request->getArguments();
        $pageUid = intval($args['pageUid']);
        $languageUid = $args['languageUid'];

        $products = $this->productRepository->findByPidRecursively($pageUid, $languageUid);
        $properties = $this->propertyRepository->findAll();

        $rows = [];

        // Collect table header information
        $col = [];
        $col[] = 'SKU';
        $col[] = 'Name';
        $col[] = 'Keywords';
        $col[] = 'Description';
        $col[] = 'DescriptionFullWidth';
        $col[] = 'Features';
        $col[] = 'Delivery';
        $col[] = 'Footnotes';
        foreach ($properties as $property) {
            $name = $this->parseLabel($property->getName());
            $propertyGroup = $property->getPropertyGroup();
            if ($propertyGroup) $name = $propertyGroup->getName().' – '.$name;
            $col[] = $name;
        }
        $rows[] = $col;

        // Collect product rows
        foreach ($products as $product) {
            unset($col);
            $col = [];
            $col[] = $this->parseValue($product->getSku());
            $col[] = $this->parseValue($product->getName());
            $col[] = $this->parseValue($product->getKeywords());
            $col[] = $this->parseValue($product->getDescription());
            $col[] = $this->parseValue($product->getDescriptionFullWidth());
            $col[] = $this->parseValue($product->getFeatures());
            $col[] = $this->parseValue($product->getDelivery());
            $col[] = $this->parseValue($product->getFootnotes());

            $productProperties = $product->getDistinctDynamicProperties();

            foreach ($properties as $property) {
                $value = isset($productProperties[$property->getUid()]) ? $productProperties[$property->getUid()] : "";
                $col[] = $this->parseValue($value);
            }

            $rows[] = $col;
        }

        // Collect rows and output as CSV
        $out = fopen('php://output', 'w');
        foreach ($rows as $row) {
            fputcsv($out, $row);
        }
        fclose($out);

        header("Content-Type: text/csv");
		header("Content-Disposition: attachment; filename=Export.csv");
        return $this->htmlResponse(null);
    }

    /**
     * action downloadXML
     *
     * @return void
     */
    public function downloadXMLAction(): \Psr\Http\Message\ResponseInterface
    {
        $GLOBALS['TSFE'] = new \stdClass();
        $GLOBALS['TSFE']->gr_list = '0,-2';

//        $context = \TYPO3\CMS\Core\Utility\GeneralUtility::get(TYPO3\CMS\Core\Context::class);
//        $context->getPropertyFromAspect('frontend.user', 'groupIds');

        $args = $this->request->getArguments();
        $pageUid = intval($args['pageUid']);

        $productGroups = $this->productGroupRepository->findByPidRecursively($pageUid);
        $propertyGroups = $this->propertyGroupRepository->findAll();
        $properties = $this->propertyRepository->findAll();

        $dom = new \DOMDocument('1.0', 'utf-8');
        $dom->substituteEntities = false;
        $dom->formatOutput = true;

        $root = $dom->createElement('ProductGroups');
        $dom->appendChild($root);

        foreach ($productGroups as $productGroup) {
            $root->appendChild($g = $dom->createElement('ProductGroup'));
            $g->setAttribute('id', $productGroup->getUid());
            $g->appendChild($dom->createElement('Name', $this->parseValue($productGroup->getName())));
            $g->appendChild($dom->createElement('Subtitle', $this->parseValue($productGroup->getSubtitle())));
            $g->appendChild($dom->createElement('Short', $this->parseValueForXML($productGroup->getShort())));
            $g->appendChild($dom->createElement('Description', $this->parseValueForXML($productGroup->getDescription())));
            $g->appendChild($dom->createElement('Features', $this->parseValueForXML($productGroup->getFeatures())));
            $g->appendChild($dom->createElement('Delivery', $this->parseValueForXML($productGroup->getDelivery())));

            $products = $productGroup->getProducts();
            $g->appendChild($pRoot = $dom->createElement('Products'));

            $propertyGroups = $productGroup->getPropertyGroups();

            foreach ($products as $product) {
                $pRoot->appendChild($p = $dom->createElement('Product'));
                $p->setAttribute('id', $product->getUid());
                $p->appendChild($dom->createElement('SKU', $this->parseValue($product->getSku())));
                $p->appendChild($dom->createElement('Name', $this->parseValue($product->getName())));
                $p->appendChild($dom->createElement('Keywords', $this->parseValue($product->getKeywords())));
                $p->appendChild($dom->createElement('Description', $this->parseValueForXML($product->getDescription())));
                $p->appendChild($dom->createElement('DescriptionFullWidth', $this->parseValueForXML($product->getDescriptionFullWidth())));
                $p->appendChild($dom->createElement('Features', $this->parseValueForXML($product->getFeatures())));
                $p->appendChild($dom->createElement('Delivery', $this->parseValueForXML($product->getDelivery())));
                $p->appendChild($dom->createElement('Footnotes', $this->parseValueForXML($product->getFootnotes())));

                $images = $product->getImages()->toArray();
                if (is_array($images) && count($images) > 0) {
                    $image = $this->getImageFileName($images[0]);
                    $p->appendChild($dom->createElement('Image', $image));
                }

                $p->appendChild($propsRoot = $dom->createElement('AttributeSets'));

                $productProperties = $product->getDistinctDynamicProperties();

                foreach ($propertyGroups as $propertyGroup) {
                    $propsRoot->appendChild($propSet = $dom->createElement('AttributeSet'));
                    $propSet->setAttribute('id', $propertyGroup->getUid());
                    $propSet->appendChild($dom->createElement('Name', $this->parseValueForXML($propertyGroup->getName())));

                    $propSet->appendChild($propSetRoot = $dom->createElement('Attributes'));

                    foreach ($propertyGroup->getProperties() as $property) {
                        if ($value = $productProperties[$property->getUid()] ?? "") {
                            $propSetRoot->appendChild($prop = $dom->createElement('Attribute'));
                            $prop->setAttribute('id', $property->getUid());
                            $prop->appendChild($dom->createElement('Name', $this->parseValueForXML($property->getName())));
                            $prop->appendChild($dom->createElement('Value', $this->parseValueForXML($value)));
                        }
                    }
                }
            }
        }

        header('Content-type: text/xml; charset=utf-8');
        header("Content-Disposition: attachment; filename=Export.xml");
        return $this->htmlResponse(html_entity_decode($dom->saveXML()));
    }

    protected function parseLabel($label) {
        if (is_array($label)) $label = implode('<br>', $label);
        $label = preg_replace('/[\n\r]+/', ', ', trim($label));
        return $label;
    }

    protected function parseValueForXML($value) {
        $value = $this->parseValue($value);
        // return "\r\n<![CDATA[\r\n".$value."\r\n]]>\r\n";
        return "<![CDATA[".$value."]]>";
    }

    protected function parseValue($value) {
        if (is_array($value)) $value = implode('<br>', $value);
        $value = preg_replace('/[\n\r]+/', ', ', trim($value));
        return $value;
    }

    protected function getImageFileName($image) {
        return 'href=file://'.$image->getOriginalResource()->getOriginalFile()->getIdentifier();
    }

    /**
     * switchable Controller Migration
     *
     * @return ForwardResponse|ResponseInterface
     */
    public function switchableAction()
    {
        // Wert für 'switchableControllerActions' aus flexForm holen
        $cObjData = \nn\t3::Tsfe()->cObjData( $this->request );
        $ffData = \nn\t3::FlexForm()->parse($cObjData['pi_flexform']);

        // ... und an passende Action weiterleiten
        $action = preg_replace('/[^>]*>(.*)/', '\1', $ffData['switchableControllerActions']);
        $methodName = "{$action}Action";

        if (!method_exists($this, $methodName)) {
            return $this->htmlResponse("PayloadController->{$methodName}() exisitert nicht.");
        }

        return new ForwardResponse( $action );
    }


}
