<?php

namespace FiloBlu\Refilo\Setup;

use FiloBlu\Refilo\Remote\Connector\ConnectorConfigurationInterface;
use FiloBlu\Refilo\Remote\Connector\ConnectorConfigurationRepositoryInterface;
use FiloBlu\Refilo\Remote\IndexerConfiguration\IndexerConfigurationInterface;
use FiloBlu\Refilo\Remote\IndexerConfiguration\IndexerConfigurationRepository;
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
 * @package FiloBlu\Refilo\Setup
 */
class UpgradeSchema implements UpgradeSchemaInterface
{
    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Zend_Db_Exception
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;

        $installer->startSetup();

        if (version_compare($context->getVersion(), '1.0.1', '<')) {
            $this->installGeoSchemas($installer);
        }
        if (version_compare($context->getVersion(), '1.0.2', '<')) {
            $this->installRedirectSchema($installer);
        }

        if (version_compare($context->getVersion(), '1.0.3', '<')) {
            $this->installIndexerSchema($installer);
            $this->installConnectorSchema($installer);
        }

        if (version_compare($context->getVersion(), '1.0.4', '<')) {
            $this->upgradeCmsPagesAttributes($installer);
        }

        if (version_compare($context->getVersion(), '1.0.5', '<')) {
            $this->upgradeCmsBlocksAttributes($installer);
        }

        if (version_compare($context->getVersion(), '1.0.6', '<')) {
            $this->upgradeContentAttributes($installer);
        }

        if (version_compare($context->getVersion(), '1.0.8', '<')) {
            $this->upgradeCmsBlocksListingAttributes($installer);
        }

        if (version_compare($context->getVersion(), '1.0.9', '<')) {
            $this->upgradeCmsBlocksListingColumnSpacing($installer);
        }

        if (version_compare($context->getVersion(), '1.0.10', '<')) {
            $this->upgradeConnectors($installer);
        }

        if (version_compare($context->getVersion(), '1.0.11', '<')) {
            $this->upgradeCmsPagesRefiloTemplate($installer);
        }

        if (version_compare($context->getVersion(), '1.0.12', '<')) {
            $this->upgradeCmsBlocksListingRowSpacing($installer);
        }

        if (version_compare($context->getVersion(), '1.0.13', '<')) {
            $this->upgradeCmsBlocksCustomerGroup($installer);
        }

        if (version_compare($context->getVersion(), '1.0.14', '<')) {
            $this->upgradeCmsPagesRefiloPageIdentifier($installer);
        }

        if (version_compare($context->getVersion(), '1.0.23', '<')) {
            $this->upgradeConnectorTable($installer);
        }

        if (version_compare($context->getVersion(), '1.0.27', '<')) {
            $this->upgradeCmsBlockIdentifier($installer);
        }

        if (version_compare($context->getVersion(), '1.0.28', '<')) {
            $this->upgradeCmsPageCustomerGroup($installer);
        }

        if (version_compare($context->getVersion(), '1.0.33', '<')) {
            $this->updateConnectorConfiguration($installer);
        }

        if (version_compare($context->getVersion(), '1.0.34', '<')) {
            $this->updateIndexerConfiguration($installer);
        }

        $installer->endSetup();
    }

    /**
     * @param SchemaSetupInterface $installer
     * @throws Zend_Db_Exception
     */
    public function installGeoSchemas(SchemaSetupInterface $installer): void
    {
        if (!$installer->tableExists('filoblu_refilo_country_continent')) {
            $table = $installer->getConnection()->newTable(
                $installer->getTable('filoblu_refilo_country_continent')
            )
                ->addColumn(
                    'country_id',
                    Table::TYPE_TEXT,
                    255,
                    [
                        'nullable' => false,
                        'primary' => true,
                        'unsigned' => true,
                    ],
                    'Country Id'
                )
                ->addColumn(
                    'country_name',
                    Table::TYPE_TEXT,
                    255,
                    ['nullable' => false],
                    'Country Name'
                )->addColumn(
                    'continent_id',
                    Table::TYPE_INTEGER,
                    null,
                    ['nullable' => false],
                    'ContinentId'
                )->setComment('Refilo Countries Continent');
            $installer->getConnection()->createTable($table);
        }

        if (!$installer->tableExists('filoblu_refilo_continent')) {
            $table = $installer->getConnection()->newTable(
                $installer->getTable('filoblu_refilo_continent')
            )
                ->addColumn(
                    'continent_id',
                    Table::TYPE_INTEGER,
                    null,
                    [
                        'identity' => true,
                        'nullable' => false,
                        'primary' => true,
                        'unsigned' => true,
                    ],
                    'Continent Id'
                )
                ->addColumn(
                    'continent',
                    Table::TYPE_TEXT,
                    255,
                    ['nullable' => false],
                    'Continent'
                )->addColumn(
                    'position',
                    Table::TYPE_INTEGER,
                    null,
                    ['nullable' => false],
                    'Position'
                )->setComment('Refilo Continent');
            $installer->getConnection()->createTable($table);
        }
    }

    /**
     * @param SchemaSetupInterface $installer
     * @throws Zend_Db_Exception
     */
    public function installRedirectSchema(SchemaSetupInterface $installer): void
    {
        if (!$installer->tableExists('filoblu_refilo_redirect')) {
            $table = $installer->getConnection()->newTable(
                $installer->getTable('filoblu_refilo_redirect')
            )
                ->addColumn(
                    'id',
                    Table::TYPE_INTEGER,
                    null,
                    [
                        'identity' => true,
                        'nullable' => false,
                        'primary' => true,
                        'unsigned' => true
                    ],
                    'Id'
                )
                ->addColumn(
                    'host',
                    Table::TYPE_TEXT,
                    255,
                    [
                        'nullable' => false
                    ],
                    'Host'
                )
                ->addColumn(
                    'request_url',
                    Table::TYPE_TEXT,
                    255,
                    ['nullable' => false],
                    'Request URL'
                )->addColumn(
                    'target_url',
                    Table::TYPE_TEXT,
                    255,
                    ['nullable' => false],
                    'Target URL'
                )->addColumn(
                    'redirect_code',
                    Table::TYPE_INTEGER,
                    null,
                    ['nullable' => false],
                    'Redirect code'
                )->setComment('Refilo Redirects');
            $installer->getConnection()->createTable($table);
        }
    }

    /**
     * @param SchemaSetupInterface $installer
     * @throws Zend_Db_Exception
     */
    public function installIndexerSchema(SchemaSetupInterface $installer): void
    {
        if ($installer->tableExists(IndexerConfigurationRepository::TABLE_NAME)) {
            return;
        }

        $table = $installer->getConnection()
            ->newTable($installer->getTable(IndexerConfigurationRepository::TABLE_NAME))
            ->addColumn(
                IndexerConfigurationInterface::ID,
                Table::TYPE_INTEGER,
                null,
                [
                    'identity' => true,
                    'nullable' => false,
                    'primary' => true,
                    'unsigned' => true
                ],
                'Id'
            )
            ->addColumn(
                IndexerConfigurationInterface::INDEXER_ID,
                Table::TYPE_TEXT,
                255,
                [
                    'nullable' => false
                ],
                'Indexer ID'
            )
            ->addColumn(
                IndexerConfigurationInterface::INDEX_NAME,
                Table::TYPE_TEXT,
                255,
                [
                    'nullable' => true
                ],
                'Index Name'
            )
            ->addColumn(
                IndexerConfigurationInterface::CONNECTOR_CONFIGURATION,
                Table::TYPE_INTEGER,
                null,
                [
                    'nullable' => true,
                    'unsigned' => true
                ],
                'Connector Configuration'
            )
            ->addColumn(
                IndexerConfigurationInterface::CONFIGURATION,
                Table::TYPE_TEXT,
                65355,
                [
                    'nullable' => true
                ],
                'Configuration'
            )
            ->addIndex(
                $installer->getIdxName(
                    IndexerConfigurationRepository::TABLE_NAME,
                    [IndexerConfigurationInterface::INDEXER_ID],
                    AdapterInterface::INDEX_TYPE_UNIQUE
                ),
                [IndexerConfigurationInterface::INDEXER_ID],
                ['type' => AdapterInterface::INDEX_TYPE_UNIQUE]
            )
            ->setComment('Refilo Indexer Configuration');
        $installer->getConnection()->createTable($table);
    }

    /**
     * @param SchemaSetupInterface $installer
     * @throws Zend_Db_Exception
     */
    public function installConnectorSchema(SchemaSetupInterface $installer): void
    {
        if ($installer->tableExists(ConnectorConfigurationRepositoryInterface::TABLE_NAME)) {
            return;
        }

        $table = $installer->getConnection()
            ->newTable($installer->getTable(ConnectorConfigurationRepositoryInterface::TABLE_NAME))
            ->addColumn(
                ConnectorConfigurationInterface::ID,
                Table::TYPE_INTEGER,
                null,
                [
                    'identity' => true,
                    'nullable' => false,
                    'primary' => true,
                    'unsigned' => true
                ],
                'Id'
            )
            ->addColumn(
                ConnectorConfigurationInterface::ENABLED,
                Table::TYPE_BOOLEAN,
                null,
                [],
                'Enabled'
            )
            ->addColumn(
                ConnectorConfigurationInterface::TYPE,
                Table::TYPE_TEXT,
                255,
                [
                    'nullable' => false
                ],
                'Type'
            )
            ->addColumn(
                ConnectorConfigurationInterface::NAME,
                Table::TYPE_TEXT,
                255,
                [
                    'nullable' => false
                ],
                'Name'
            )
            ->addColumn(
                ConnectorConfigurationInterface::CONFIGURATION,
                Table::TYPE_TEXT,
                65355,
                [],
                'Configuration'
            )
            ->setComment('Refilo Connector Configuration');
        $installer->getConnection()->createTable($table);
    }

    protected function upgradeCmsPagesAttributes(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsPageTable = $installer->getTable('cms_page');

        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'refilo_layout',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Refilo Layout'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'heading_visible',
            [
                'type' => Table::TYPE_BOOLEAN,
                'nullable' => true,
                'comment' => 'Heading Visible'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'breadcrumbs_visible',
            [
                'type' => Table::TYPE_BOOLEAN,
                'nullable' => true,
                'comment' => 'Breadcrumbs Visible'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'og_data_image',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'OG Data Image'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'header_type',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Header Type'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'css_class',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'CSS Class'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'css_style',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Custom CSS'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'robots',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Robots SEO'
            ]
        );

        $installer->endSetup();
    }

    public function upgradeCmsBlocksAttributes(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsBlockTable = $installer->getTable('cms_block');

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'display_on',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Specific entity display selection'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'selection_type',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Type of display selection'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'selection_target',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Specific target based on selection'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'refilo_layout_container',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Layout container target'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'refilo_layout_order',
            [
                'type' => Table::TYPE_INTEGER,
                'nullable' => true,
                'comment' => 'Layout sort order'
            ]
        );

        $installer->endSetup();
    }

    public function upgradeContentAttributes(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsPageTable = $installer->getTable('blackbird_contenttype');

        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'refilo_layout',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Refilo Layout'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'heading_visible',
            [
                'type' => Table::TYPE_BOOLEAN,
                'nullable' => true,
                'comment' => 'Heading Visible'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'breadcrumbs_visible',
            [
                'type' => Table::TYPE_BOOLEAN,
                'nullable' => true,
                'comment' => 'Breadcrumbs Visible'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'header_type',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Header Type'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'css_class',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'CSS Class'
            ]
        );
        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'css_style',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Custom CSS'
            ]
        );

        $installer->endSetup();
    }

    public function upgradeCmsBlocksListingAttributes(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsBlockTable = $installer->getTable('cms_block');

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'listing_display_page',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Page of listing where block is visible'
            ]
        );

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'listing_display_position',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Listing position where block is visible'
            ]
        );

        $installer->endSetup();
    }

    public function upgradeCmsBlocksListingColumnSpacing(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsBlockTable = $installer->getTable('cms_block');

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'listing_columns_spacing',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Block spacing among products'
            ]
        );

        $installer->endSetup();
    }

    public function upgradeConnectors(SchemaSetupInterface $installer)
    {
        $installer->startSetup();
        $cmsBlockTable = $installer->getTable(IndexerConfigurationRepository::TABLE_NAME);

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            IndexerConfigurationInterface::ENABLED,
            [
                'type' => Table::TYPE_BOOLEAN,
                'nullable' => true,
                'comment' => 'Enable or disable indexer'
            ]
        );

        $installer->endSetup();
    }

    public function upgradeCmsPagesRefiloTemplate(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsPageTable = $installer->getTable('cms_page');

        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'refilo_template',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Refilo Template'
            ]
        );

        $installer->endSetup();
    }

    public function upgradeCmsBlocksListingRowSpacing(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsBlockTable = $installer->getTable('cms_block');

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'listing_row_spacing',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Block spacing among products'
            ]
        );

        $installer->endSetup();
    }

    public function upgradeCmsBlocksCustomerGroup(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsBlockTable = $installer->getTable('cms_block');

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'customer_group',
            [
                'type' => Table::TYPE_TEXT,
                'length' => 255,
                'nullable' => true,
                'comment' => 'Customer Group'
            ]
        );

        $installer->endSetup();
    }

    /**
     * @param SchemaSetupInterface $installer
     */
    public function upgradeCmsPagesRefiloPageIdentifier(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsPageTable = $installer->getTable('cms_page');

        $installer->getConnection()->addColumn(
            $cmsPageTable,
            'refilo_page_identifier',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Refilo Page Identifier'
            ]
        );

        $installer->endSetup();
    }

    /**
     * @param \Magento\Framework\Setup\SchemaSetupInterface $installer
     * @return void
     */
    public function upgradeConnectorTable(SchemaSetupInterface $installer)
    {
        if (!$installer->tableExists(IndexerConfigurationRepository::TABLE_NAME)) {
            return;
        }
        $installer->getConnection()->modifyColumn(
            $installer->getTable(IndexerConfigurationRepository::TABLE_NAME),
            IndexerConfigurationInterface::CONNECTOR_CONFIGURATION,
            [
                'type' => Table::TYPE_INTEGER,
                'nullable' => true
            ]
        );
    }

    /**
     * @param \Magento\Framework\Setup\SchemaSetupInterface $installer
     * @return void
     */
    public function upgradeCmsBlockIdentifier(SchemaSetupInterface $installer)
    {

        $installer->startSetup();
        $cmsBlockTable = $installer->getTable('cms_block');


        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'refilo_identifier',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Refilo Identifier'
            ]
        );


        $installer->endSetup();
    }

    public function upgradeCmsPageCustomerGroup(SchemaSetupInterface $installer): void
    {
        $installer->startSetup();
        $cmsBlockTable = $installer->getTable('cms_page');

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            'customer_group',
            [
                'type' => Table::TYPE_TEXT,
                'length' => 255,
                'nullable' => true,
                'comment' => 'Customer Group'
            ]
        );

        $installer->endSetup();
    }

    /**
     * @param \Magento\Framework\Setup\SchemaSetupInterface $installer
     * @return void
     */
    public function updateConnectorConfiguration(SchemaSetupInterface $installer)
    {
        $installer->startSetup();
        $cmsBlockTable = $installer->getTable(IndexerConfigurationRepository::TABLE_NAME);

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            IndexerConfigurationInterface::ALLOW_DELETE,
            [
                'type' => Table::TYPE_BOOLEAN,
                'nullable' => true,
                'comment' => 'Allow indexer to delete removed entities'
            ]
        );

        $installer->getConnection()->addColumn(
            $cmsBlockTable,
            IndexerConfigurationInterface::DELETE_ORDER,
            [
                'type' => Table::TYPE_INTEGER,
                'nullable' => true,
                'comment' => 'Delete after of before indexer runs'
            ]
        );

        $installer->endSetup();
    }

    /**
     * @param \Magento\Framework\Setup\SchemaSetupInterface $installer
     * @return void
     */
    public function updateIndexerConfiguration(SchemaSetupInterface $installer)
    {
        $installer->startSetup();
        $indexerConfigurationTable = $installer->getTable(IndexerConfigurationRepository::TABLE_NAME);

        $installer->getConnection()->addColumn(
            $indexerConfigurationTable,
            IndexerConfigurationInterface::ENABLED_MEMORY_OPTIMIZATION,
            [
                'type' => Table::TYPE_BOOLEAN,
                'nullable' => true,
                'comment' => 'Allow memory usage optimization'
            ]
        );

        $installer->endSetup();
    }
}
