<?php

namespace FiloBlu\ActiveCampaign\Setup;

use Exception;
use FiloBlu\ActiveCampaign\Api\Data\FieldsInterface;
use FiloBlu\ActiveCampaign\Api\Data\JobsInterface;
use FiloBlu\ActiveCampaign\Api\Data\ListsInterface;
use FiloBlu\ActiveCampaign\Model\Config\Source\JobStatus;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Zend_Db_Exception;

/**
 * @codeCoverageIgnore
 */
class InstallSchema implements InstallSchemaInterface
{
    /**
     * {@inheritdoc}
     * @throws Zend_Db_Exception
     */
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        $this->createActiveCampaignJobsTable($setup, $context);
        $this->createActiveCampaignListsTable($setup, $context);
        $this->createActiveCampaignFieldsTable($setup, $context);
        $setup->endSetup();
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Zend_Db_Exception
     */
    public function createActiveCampaignJobsTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (!$setup->tableExists(JobsInterface::DB_TABLE)) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable(JobsInterface::DB_TABLE)
            )
                ->addColumn(
                    JobsInterface::ID,
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'Job id'
                )
                ->addColumn(
                    JobsInterface::TYPE,
                    Table::TYPE_TEXT,
                    '100',
                    ['nullable' => false],
                    'Job type'
                )
                ->addColumn(
                    JobsInterface::DIRECTION,
                    Table::TYPE_TEXT,
                    '100',
                    ['nullable' => false],
                    'Job direction'
                )
                ->addColumn(
                    JobsInterface::ENTITY,
                    Table::TYPE_TEXT,
                    '100',
                    ['nullable' => false],
                    'Job entity'
                )
                ->addColumn(
                    JobsInterface::ENTITY_ID,
                    Table::TYPE_INTEGER,
                    null,
                    ['nullable' => false, 'unsigned' => true],
                    'Job entity_id'
                )
                ->addColumn(
                    JobsInterface::REQUEST,
                    Table::TYPE_TEXT,
                    '64k',
                    [],
                    'Job request'
                )
                ->addColumn(
                    JobsInterface::RESPONSE,
                    Table::TYPE_TEXT,
                    '64k',
                    [],
                    'Job response'
                )
                ->addColumn(
                    JobsInterface::STATUS,
                    Table::TYPE_TEXT,
                    '50',
                    ['nullable' => false, 'default' => JobStatus::JOB_STATUS_WAITING],
                    'Job status'
                )
                ->addColumn(
                    JobsInterface::LOG,
                    Table::TYPE_TEXT,
                    '64k',
                    [],
                    'log'
                )
                ->addColumn(
                    JobsInterface::CREATED_AT,
                    Table::TYPE_TIMESTAMP,
                    null,
                    ['nullable' => false, 'default' => Table::TIMESTAMP_INIT],
                    'Job created at'
                )
                ->addColumn(
                    JobsInterface::UPDATED_AT,
                    Table::TYPE_TIMESTAMP,
                    null,
                    ['nullable' => false, 'default' => Table::TIMESTAMP_INIT_UPDATE],
                    'Job updated at'
                )
                ->addIndex(
                    $setup->getIdxName(
                        JobsInterface::DB_TABLE,
                        [JobsInterface::DIRECTION, JobsInterface::ENTITY, JobsInterface::ENTITY_ID],
                        AdapterInterface::INDEX_TYPE_UNIQUE
                    ),
                    [JobsInterface::DIRECTION, JobsInterface::ENTITY, JobsInterface::ENTITY_ID],
                    ['type' => AdapterInterface::INDEX_TYPE_UNIQUE]
                );

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

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Zend_Db_Exception
     */
    public function createActiveCampaignListsTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (!$setup->tableExists(ListsInterface::DB_TABLE)) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable(ListsInterface::DB_TABLE)
            )
                ->addColumn(
                    ListsInterface::ID,
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'List id'
                )
                ->addColumn(
                    ListsInterface::AC_ID,
                    Table::TYPE_INTEGER,
                    null,
                    ['nullable' => false],
                    'List Active Campaign ID'
                )
                ->addColumn(
                    ListsInterface::NAME,
                    Table::TYPE_TEXT,
                    '255',
                    ['nullable' => false],
                    'List name'
                )
                ->addIndex(
                    $setup->getIdxName(
                        ListsInterface::DB_TABLE,
                        [ListsInterface::AC_ID],
                        AdapterInterface::INDEX_TYPE_UNIQUE
                    ),
                    [ListsInterface::AC_ID],
                    ['type' => AdapterInterface::INDEX_TYPE_UNIQUE]
                );

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

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Zend_Db_Exception
     */
    public function createActiveCampaignFieldsTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (!$setup->tableExists(FieldsInterface::DB_TABLE)) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable(FieldsInterface::DB_TABLE)
            )
                ->addColumn(
                    FieldsInterface::ID,
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'Field id'
                )
                ->addColumn(
                    FieldsInterface::AC_ID,
                    Table::TYPE_INTEGER,
                    null,
                    ['nullable' => false],
                    'Active Campaign Field ID'
                )
                ->addColumn(
                    FieldsInterface::NAME,
                    Table::TYPE_TEXT,
                    '255',
                    ['nullable' => false],
                    'Field name'
                )
                ->addIndex(
                    $setup->getIdxName(
                        FieldsInterface::DB_TABLE,
                        [FieldsInterface::AC_ID],
                        AdapterInterface::INDEX_TYPE_UNIQUE
                    ),
                    [FieldsInterface::AC_ID],
                    ['type' => AdapterInterface::INDEX_TYPE_UNIQUE]
                );

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