<?php
/**
 * Created by PhpStorm.
 * User: jderosa
 * Date: 21/02/20
 * Time: 11.57
 */

namespace FiloBlu\Rma\Setup;

use FiloBlu\Rma\Api\RmaExtensionAttributesRepositoryInterface;
use FiloBlu\Rma\Model\ResourceModel\EasyReturn;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Zend_Db_Exception;

/**
 *
 */
class UpgradeSchema implements UpgradeSchemaInterface
{
    /** @var string */
    const EASY_RETURN_MATRIXRATE_TABLE = 'filoblu_easy_return_matrixrate';
    const CHANGE_SIZE_MATRIXRATE_TABLE = 'filoblu_change_size_matrixrate';

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Zend_Db_Exception
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        if (!$setup->tableExists(RmaExtensionAttributesRepositoryInterface::TABLE_NAME)) {
            $this->createFiloBluRmaItemTable($setup);
        }

        if (!$setup->tableExists(EasyReturn::TABLE_NAME)) {
            $this->createEasyReturnTable($setup);
        } else {
            if (version_compare($context->getVersion(), '2.2.0', '<=')) {
                $this->updateEasyRmaTableSchema($setup);
            }
        }

        if (!$setup->tableExists(self::EASY_RETURN_MATRIXRATE_TABLE)) {
            $this->createReturnMatrixRateTable($setup);
        }

        $this->createRmaItemResolutionHistory($setup);

        if (version_compare($context->getVersion(), '2.2.9', '<=')) {
            if (!$setup->tableExists(self::CHANGE_SIZE_MATRIXRATE_TABLE)) {
                $this->createChangeSizeMatrixRateTable($setup);
            }
        }

        if (version_compare($context->getVersion(), '2.2.9', '<=')) {
            if ($setup->tableExists(EasyReturn::TABLE_NAME)) {
                $this->updateTheoricShippingAmountColumn($setup);
            }
        }

        if (version_compare($context->getVersion(), '2.2.11', '<=')) {
            $this->updateSalesRuleTable($setup);
        }

        if (version_compare($context->getVersion(), '2.2.11', '<=')) {
            $this->updateSalesOrderItemTable($setup);
        }

        $setup->endSetup();
    }

    /**
     * @param SchemaSetupInterface $setup
     * @throws Zend_Db_Exception
     */
    protected function createFiloBluRmaItemTable(SchemaSetupInterface $setup)
    {
        $table = $setup->getConnection()
            ->newTable($setup->getConnection()->getTableName(RmaExtensionAttributesRepositoryInterface::TABLE_NAME))
            ->addColumn(
                'id',
                Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                'id'
            )
            ->addColumn(
                'rma_item_id',
                Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => false],
                'rma_entity_id'
            )
            ->addColumn(
                'order_id',
                Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => false],
                'order_id'
            );
        $setup->getConnection()->createTable($table);
    }

    /**
     * @param SchemaSetupInterface $setup
     * @throws Zend_Db_Exception
     */
    protected function createEasyReturnTable(SchemaSetupInterface $setup)
    {
        $tableName = $setup->getConnection()->getTableName(EasyReturn::TABLE_NAME);
        $parentTableName = $setup->getConnection()->getTableName('magento_rma');
        $table = $setup->getConnection()
            ->newTable($tableName)
            ->addColumn(
                'id',
                Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                'id'
            )
            ->addColumn(
                'rma_entity_id',
                Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => false],
                'rma_entity_id'
            )
            ->addColumn(
                'customer_firstname',
                Table::TYPE_TEXT,
                null,
                ['nullable' => false],
                'customer_firstname'
            )
            ->addColumn(
                'customer_lastname',
                Table::TYPE_TEXT,
                null,
                ['nullable' => false],
                'customer_lastname'
            )
            ->addColumn(
                'street',
                Table::TYPE_TEXT,
                null,
                ['nullable' => false],
                'street'
            )
            ->addColumn(
                'city',
                Table::TYPE_TEXT,
                null,
                ['nullable' => false],
                'city'
            )
            ->addColumn(
                'region_id',
                Table::TYPE_INTEGER,
                null,
                ['nullable' => false],
                'region_id'
            )
            ->addColumn(
                'region',
                Table::TYPE_TEXT,
                null,
                ['nullable' => false],
                'region'
            )
            ->addColumn(
                'postcode',
                Table::TYPE_TEXT,
                null,
                ['nullable' => false],
                'postcode'
            )
            ->addColumn(
                'country_id',
                Table::TYPE_TEXT,
                null,
                ['nullable' => false],
                'country_id'
            )
            ->addColumn(
                'telephone',
                Table::TYPE_TEXT,
                null,
                ['nullable' => false],
                'telephone'
            )
            ->addColumn(
                'theoric_shipping_amount',
                Table::TYPE_FLOAT,
                null,
                ['nullable' => false, 'precision' => 12, 'scale' => 4],
                'theoric_shipping_amount'
            )
            ->addIndex(
                $setup->getIdxName(
                $tableName,
                ['rma_entity_id'],
                AdapterInterface::INDEX_TYPE_UNIQUE
            ),
                ['rma_entity_id'],
                ['type' => AdapterInterface::INDEX_TYPE_UNIQUE]
            )
            ->addForeignKey(
                $setup->getFkName($tableName, 'rma_entity_id', $parentTableName, 'entity_id'),
                'rma_entity_id',
                $setup->getTable($parentTableName),
                'entity_id',
                Table::ACTION_CASCADE
            );

        $setup->getConnection()->createTable($table);
    }

    /**
     * @param SchemaSetupInterface $setup
     */
    public function updateEasyRmaTableSchema(SchemaSetupInterface $setup)
    {
        $setup->getConnection()
            ->addColumn(
                $setup->getTable(EasyReturn::TABLE_NAME),
                'telephone',
                [
                    'type'     => Table::TYPE_TEXT,
                    'lenght'   => null,
                    'nullable' => false,
                    'comment'  => 'telephone'
                ]
            );
    }

    /**
     * @param SchemaSetupInterface $setup
     * @throws Zend_Db_Exception
     */
    protected function createReturnMatrixRateTable(SchemaSetupInterface $setup)
    {
        /**
         * Create table 'filoblu_easy_return_matrixrate'
         */
        $table = $setup->getConnection()->newTable(
            $setup->getTable('filoblu_easy_return_matrixrate')
        )->addColumn(
            'pk',
            Table::TYPE_INTEGER,
            null,
            ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
            'Primary key'
        )->addColumn(
            'website_id',
            Table::TYPE_INTEGER,
            null,
            ['nullable' => false, 'default' => '0'],
            'Website Id'
        )->addColumn(
            'dest_country_id',
            Table::TYPE_TEXT,
            4,
            ['nullable' => false, 'default' => '0'],
            'Destination coutry ISO/2 or ISO/3 code'
        )->addColumn(
            'dest_region_id',
            Table::TYPE_INTEGER,
            null,
            ['nullable' => false, 'default' => '0'],
            'Destination Region Id'
        )->addColumn(
            'dest_city',
            Table::TYPE_TEXT,
            30,
            ['nullable' => false, 'default' => ''],
            'Destination City'
        )->addColumn(
            'dest_zip',
            Table::TYPE_TEXT,
            10,
            ['nullable' => false, 'default' => '*'],
            'Destination Post Code (Zip)'
        )->addColumn(
            'dest_zip_to',
            Table::TYPE_TEXT,
            10,
            ['nullable' => false, 'default' => '*'],
            'Destination Post Code To (Zip)'
        )->addColumn(
            'condition_name',
            Table::TYPE_TEXT,
            20,
            ['nullable' => false],
            'Rate Condition name'
        )->addColumn(
            'condition_from_value',
            Table::TYPE_DECIMAL,
            '12,4',
            ['nullable' => false, 'default' => '0.0000'],
            'Rate condition from value'
        )->addColumn(
            'condition_to_value',
            Table::TYPE_DECIMAL,
            '12,4',
            ['nullable' => false, 'default' => '0.0000'],
            'Rate condition to value'
        )->addColumn(
            'price',
            Table::TYPE_DECIMAL,
            '12,4',
            ['nullable' => false, 'default' => '0.0000'],
            'Price'
        )->addColumn(
            'cost',
            Table::TYPE_DECIMAL,
            '12,4',
            ['nullable' => false, 'default' => '0.0000'],
            'Cost'
        )->addColumn(
            'shipping_method',
            Table::TYPE_TEXT,
            255,
            ['nullable' => false],
            'Shipping Method'
        )->addIndex(
            $setup->getIdxName(
                'filoblu_easy_return_matrixrate',
                [
                    'website_id', 'dest_country_id', 'dest_region_id', 'dest_city', 'dest_zip', 'condition_name',
                    'condition_from_value', 'condition_to_value', 'shipping_method'],
                AdapterInterface::INDEX_TYPE_UNIQUE
            ),
            [
                'website_id', 'dest_country_id', 'dest_region_id', 'dest_city', 'dest_zip', 'condition_name',
                'condition_from_value', 'condition_to_value', 'shipping_method'],
            ['type' => AdapterInterface::INDEX_TYPE_UNIQUE]
        )->setComment(
            'FiloBlu Easy Return Shipping MatrixRate'
        );
        $setup->getConnection()->createTable($table);
    }

    protected function createRmaItemResolutionHistory(SchemaSetupInterface $setup)
    {
        $tableName = $setup->getTable('filoblu_rma_items_resolution_history');

        if ($setup->getConnection()->isTableExists($tableName)) {
            return false;
        }

        $table = $setup->getConnection()
            ->newTable($tableName)
            ->addColumn(
                'id',
                Table::TYPE_INTEGER,
                null,
                [
                    'identity' => true,
                    'unsigned' => true,
                    'nullable' => false,
                    'primary'  => true
                ],
                'ID'
            )
            ->addColumn(
                'item_id',
                Table::TYPE_INTEGER,
                null,
                ['nullable' => false],
                'Rma Item Entity ID'
            )
            ->addColumn(
                'parent_id',
                Table::TYPE_INTEGER,
                null,
                ['nullable' => false],
                'Rma Entity ID'
            )
            ->addColumn(
                'parent_increment_id',
                Table::TYPE_TEXT,
                50,
                ['nullable' => false],
                'Rma Increment ID'
            )
            ->addColumn(
                'resolution',
                Table::TYPE_TEXT,
                255,
                ['nullable' => false],
                'Resolution'
            )
            ->addColumn(
                'url',
                Table::TYPE_TEXT,
                255,
                [],
                'URL'
            )
            ->addColumn(
                'created_at',
                Table::TYPE_TIMESTAMP,
                null,
                ['nullable' => false, 'default' => Table::TIMESTAMP_INIT],
                'Created At'
            )
            ->addColumn(
                'updated_at',
                Table::TYPE_TIMESTAMP,
                null,
                ['nullable' => false, 'default' => Table::TIMESTAMP_UPDATE],
                'Updated At'
            )
            ->setComment('Filoblu RMA Resolution History Table');

        $setup->getConnection()->createTable($table);
    }

    /**
     * @param SchemaSetupInterface $setup
     * @throws Zend_Db_Exception
     */
    protected function createChangeSizeMatrixRateTable(SchemaSetupInterface $setup)
    {
        /**
         * Create table 'filoblu_change_size_matrixrate'
         */
        $table = $setup->getConnection()->newTable(
            $setup->getTable('filoblu_change_size_matrixrate')
        )->addColumn(
            'pk',
            Table::TYPE_INTEGER,
            null,
            ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
            'Primary key'
        )->addColumn(
            'website_id',
            Table::TYPE_INTEGER,
            null,
            ['nullable' => false, 'default' => '0'],
            'Website Id'
        )->addColumn(
            'dest_country_id',
            Table::TYPE_TEXT,
            4,
            ['nullable' => false, 'default' => '0'],
            'Destination coutry ISO/2 or ISO/3 code'
        )->addColumn(
            'dest_region_id',
            Table::TYPE_INTEGER,
            null,
            ['nullable' => false, 'default' => '0'],
            'Destination Region Id'
        )->addColumn(
            'dest_city',
            Table::TYPE_TEXT,
            30,
            ['nullable' => false, 'default' => ''],
            'Destination City'
        )->addColumn(
            'dest_zip',
            Table::TYPE_TEXT,
            10,
            ['nullable' => false, 'default' => '*'],
            'Destination Post Code (Zip)'
        )->addColumn(
            'dest_zip_to',
            Table::TYPE_TEXT,
            10,
            ['nullable' => false, 'default' => '*'],
            'Destination Post Code To (Zip)'
        )->addColumn(
            'condition_name',
            Table::TYPE_TEXT,
            20,
            ['nullable' => false],
            'Rate Condition name'
        )->addColumn(
            'condition_from_value',
            Table::TYPE_DECIMAL,
            '12,4',
            ['nullable' => false, 'default' => '0.0000'],
            'Rate condition from value'
        )->addColumn(
            'condition_to_value',
            Table::TYPE_DECIMAL,
            '12,4',
            ['nullable' => false, 'default' => '0.0000'],
            'Rate condition to value'
        )->addColumn(
            'price',
            Table::TYPE_DECIMAL,
            '12,4',
            ['nullable' => false, 'default' => '0.0000'],
            'Price'
        )->addColumn(
            'cost',
            Table::TYPE_DECIMAL,
            '12,4',
            ['nullable' => false, 'default' => '0.0000'],
            'Cost'
        )->addColumn(
            'shipping_method',
            Table::TYPE_TEXT,
            255,
            ['nullable' => false],
            'Shipping Method'
        )->addIndex(
            $setup->getIdxName(
                'filoblu_change_size_matrixrate',
                [
                    'website_id',
                    'dest_country_id',
                    'dest_region_id',
                    'dest_city',
                    'dest_zip',
                    'condition_name',
                    'condition_from_value',
                    'condition_to_value',
                    'shipping_method'
                ],
                AdapterInterface::INDEX_TYPE_UNIQUE
            ),
            [
                'website_id',
                'dest_country_id',
                'dest_region_id',
                'dest_city',
                'dest_zip',
                'condition_name',
                'condition_from_value',
                'condition_to_value',
                'shipping_method'
            ],
            ['type' => AdapterInterface::INDEX_TYPE_UNIQUE]
        )->setComment(
            'FiloBlu Change Size Shipping MatrixRate'
        );
        $setup->getConnection()->createTable($table);
    }

    public function updateTheoricShippingAmountColumn($setup)
    {
        $setup->getConnection()
            ->changeColumn(
                $setup->getTable(EasyReturn::TABLE_NAME),
                'theoric_shipping_amount',
                'theoric_shipping_amount',
                [
                    'type'     => Table::TYPE_FLOAT,
                    'nullable' => false,
                    'precision' => 12,
                    'scale' => 4,
                ]
            );
    }

    public function updateSalesRuleTable(SchemaSetupInterface $setup)
    {
        $setup->getConnection()->addColumn(
            $setup->getTable('salesrule'),
            'free_return_shipping',
            [
                'type' => Table::TYPE_SMALLINT,
                'nullable' => true,
                'default' => 0,
                'comment' => 'Free Return Shipping'
            ]
        );
    }

    public function updateSalesOrderItemTable(SchemaSetupInterface $setup)
    {
        $setup->getConnection()->addColumn(
            $setup->getTable('sales_order_item'),
            'free_return_shipping',
            [
                'type' => Table::TYPE_SMALLINT,
                'nullable' => true,
                'default' => 0,
                'comment' => 'Free Return Shipping'
            ]
        );
    }

}
