<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonShippingCommon\Controllers\Backend;

use Shopware\Components\CSRFWhitelistAware;
use Shopware\Plugins\ViisonCommon\Controllers\ViisonCommonBaseController;
use Shopware\Plugins\ViisonShippingCommon\Classes\DailyClosingGenerator;

/**
 * This controller provides two backend actions for getting a list of all shops
 * as well as for displaying daily closing reports.
 */
class ViisonShippingCommonDailyClosing extends ViisonCommonBaseController implements CSRFWhitelistAware
{
    protected $dailyClosingGenerator;

    public function __construct(\Enlight_Controller_Request_Request $request = null, \Enlight_Controller_Response_Response $response = null, DailyClosingGenerator $dailyClosingGenerator = null)
    {
        parent::__construct($request, $response);
        $this->dailyClosingGenerator = $dailyClosingGenerator;
    }

    /**
     * Disables the renderer and output buffering for all 'getDailyClosing' requests
     * to be able to display PDFs as response.
     */
    public function init()
    {
        parent::init();
        if ($this->Request()->getActionName() === 'getDailyClosing') {
            Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
            $this->Front()->setParam('disableOutputBuffering', true);
        }
    }

    /**
     * Don't use the JSON renderer for the 'getDailyClosing' action.
     */
    public function preDispatch()
    {
        if (!in_array($this->Request()->getActionName(), array('index', 'load', 'skeleton', 'extends', 'getDailyClosing'))) {
            $this->Front()->Plugins()->Json()->setRenderer();
        }
    }

    /* Actions */

    /**
     * Fetches all shops from the database and adds their ids and names to the response.
     */
    public function getShopsAction()
    {
        // Fetch the names and ids of all shops
        $shops = Shopware()->Models()->getRepository('Shopware\Models\Shop\Shop')->findAll();

        // Prepare the response data
        $data = array();
        foreach ($shops as $shop) {
            $data[] = array(
                'id' => $shop->getId(),
                'name' => $shop->getName()
            );
        }

        $this->View()->assign(array(
            'success' => true,
            'data' => $data,
            'total' => count($data)
        ));
    }

    /**
     * Creates a daily closing document for the given timespan.
     */
    public function getDailyClosingAction()
    {
        // Get the mandatory shop id
        $shopId = $this->Request()->getParam('shopId', null);
        if (is_null($shopId)) {
            echo 'Error: Missing parameter "shopId".';
            return;
        }

        // shopId = '0' means that the daily closing should be created for all subshops
        if ($shopId === '0') {
            $shopId = null;
        }

        // Get the from and to dates from the request
        $fromDate = $this->Request()->getParam('from', date('Y-m-d H:i:s'));
        $toDate = $this->Request()->getParam('to', date('Y-m-d H:i:s'));

        // For plugins that do not support a date range, the date is given in the 'date' parameter
        $date = $this->Request()->getParam('date', null);
        if (!is_null($date)) {
            $fromDate = $date;
            $toDate = $date;
        }

        try {
            // Request the manifest
            if ($this->Request()->getParam('onlyNewLabels', false)) {
                $result = $this->dailyClosingGenerator->getDailyClosingForNewLabels($shopId);
            } else {
                $result = $this->dailyClosingGenerator->getDailyClosing($shopId, $fromDate, $toDate);
            }

            // Write the manifest to the output
            $this->respondWithPDF($result, 'manifest.pdf');
        } catch (\Exception $e) {
            // Just echo the error message
            echo 'Error: ' . $e->getMessage();
        }
    }

    /**
     * Sets the necessary header values to prepare a PDF file transfer in the response
     * and finally writes the data from the given buffer to the output stream.
     *
     * @param string $pdfBuffer The binary buffer containing the PDF file.
     * @param string $displayName The name which should be used for the file in the response headers.
     */
    private function respondWithPDF($pdfBuffer, $displayName)
    {
        // Set necessary headers
        $this->Response()->setHeader('Content-Type', 'application/pdf', true);
        $this->Response()->setHeader('Content-Disposition', ('inline; filename=' . $displayName), true);
        $this->Response()->sendHeaders();

        // Return the PDF
        echo $pdfBuffer;
    }

    /**
     * @override
     */
    public function getWhitelistedCSRFActions()
    {
        return array(
            'getDailyClosing'
        );
    }
}
