<?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\ViisonDHL\Components;

use Shopware\Plugins\ViisonShippingCommon\Classes\ShippingDocumentType;
use Shopware\Plugins\ViisonShippingCommon\Structs\PageSize;

class ShippingDocumentTypeFactoryService
{
    const LABEL_TYPE_EXPORT_DOCUMENT = 'export_document';
    const LABEL_TYPE_RETURN_LABEL = 'return_label';
    const LABEL_TYPE_SHIPPING_LABEL = 'shipping_label';

    const DOCUMENT_TYPE_ID_LABEL_A5 = 1;
    const DOCUMENT_TYPE_ID_EXPORT_A4 = 3;
    const DOCUMENT_TYPE_ID_RETURN_LABEL_A4 = 4;

    const PAGE_SIZE_A4 = 'A4';
    const PAGE_SIZE_A5 = 'A5';

    /**
     * @var \Enlight_Components_Snippet_Namespace
     */
    private $snippetNamespace;

    /**
     * @var \Shopware_Components_Snippet_Manager
     */
    private $snippets;

    /**
     * @param \Shopware_Components_Snippet_Manager
     */
    public function __construct($snippets)
    {
        $this->snippets = $snippets;
    }

    /**
     * @return ShippingDocumentType[]
     */
    public function getAvailableDocumentTypes()
    {
        $documentTypes = [
            $this->createExportDocumentType(),
            $this->createLabelDocumentType(),
            $this->createReturnLabelDocumentType(),
        ];

        return $documentTypes;
    }

    /**
     * @return ShippingDocumentType
     */
    public function createExportDocumentType()
    {
        return $this->createDocumentType(self::LABEL_TYPE_EXPORT_DOCUMENT, self::PAGE_SIZE_A4);
    }

    /**
     * @return ShippingDocumentType
     */
    public function createLabelDocumentType()
    {
        return $this->createDocumentType(self::LABEL_TYPE_SHIPPING_LABEL, self::PAGE_SIZE_A5);
    }

    /**
     * @return ShippingDocumentType
     */
    public function createReturnLabelDocumentType()
    {
        return $this->createDocumentType(self::LABEL_TYPE_RETURN_LABEL, self::PAGE_SIZE_A4);
    }

    /**
     * @param string $labelType
     * @param string $pageSizeIdentifier
     * @return ShippingDocumentType
     */
    private function createDocumentType($labelType, $pageSizeIdentifier)
    {
        $documentTypeId = $this->getDocumentTypeId($labelType, $pageSizeIdentifier);

        return new ShippingDocumentType(
            $documentTypeId,
            $this->getDocumentTypeName($documentTypeId),
            $this->createPageSize($pageSizeIdentifier)
        );
    }

    /**
     * @param int $documentTypeId
     * @return string
     */
    private function getDocumentTypeName($documentTypeId)
    {
        $snippetNames = [
            self::DOCUMENT_TYPE_ID_EXPORT_A4 => 'export_document/name',
            self::DOCUMENT_TYPE_ID_LABEL_A5 => 'shipping_label/name',
            self::DOCUMENT_TYPE_ID_RETURN_LABEL_A4 => 'return_label/name',
        ];

        return $this->getSnippetNamespace()->get($snippetNames[$documentTypeId]);
    }

    /**
     * Creates the PageSize object from its identifier string.
     *
     * @param string $identifier
     * @return PageSize
     */
    private function createPageSize($identifier)
    {
        switch ($identifier) {
            case self::PAGE_SIZE_A4:
                return new PageSize(
                    self::PAGE_SIZE_A4,
                    210,
                    297
                );

            case self::PAGE_SIZE_A5:
                return new PageSize(
                    self::PAGE_SIZE_A5,
                    148,
                    210
                );
        }
    }

    /**
     * @param string $labelType
     * @param string $pageSizeIdentifier
     * @return int
     */
    private function getDocumentTypeId($labelType, $pageSizeIdentifier)
    {
        $documentTypes = [
            self::LABEL_TYPE_RETURN_LABEL => [
                self::PAGE_SIZE_A4 => self::DOCUMENT_TYPE_ID_RETURN_LABEL_A4,
            ],
            self::LABEL_TYPE_SHIPPING_LABEL => [
                self::PAGE_SIZE_A5 => self::DOCUMENT_TYPE_ID_LABEL_A5,
            ],
            self::LABEL_TYPE_EXPORT_DOCUMENT => [
                self::PAGE_SIZE_A4 => self::DOCUMENT_TYPE_ID_EXPORT_A4,
            ],
        ];

        if (isset($documentTypes[$labelType][$pageSizeIdentifier])) {
            return $documentTypes[$labelType][$pageSizeIdentifier];
        }

        throw new \InvalidArgumentException(sprintf(
            'The document type "%s" can not exist with a page size of "%s".',
            $labelType,
            $pageSizeIdentifier
        ));
    }

    /**
     * @return \Enlight_Components_Snippet_Namespace
     */
    private function getSnippetNamespace()
    {
        if (!$this->snippetNamespace) {
            $this->snippetNamespace = $this->snippets->getNamespace('backend/viison_dhl_document_types/main');
        }

        return $this->snippetNamespace;
    }
}
