<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Setup;

use Blackbird\ContentManager\Model\Content;
use FiloBlu\Refilo\Model\Product\Attribute\Backend\RefiloChildrenCategoriesEnabled;
use FiloBlu\Refilo\Model\Product\Attribute\Backend\RefiloSiblingsCategoriesEnabled;
use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\Category\Attribute\Backend\Image;
use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Model\Entity\Attribute\Source\Boolean;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Zend_Locale;
use Zend_Validate_Exception;
use Magento\Customer\Setup\CustomerSetupFactory;

/**
 *
 */
class UpgradeData implements UpgradeDataInterface
{
    /**
     * @var EavSetupFactory
     */
    protected $eavSetupFactory;

    /**
     * @var CustomerSetupFactory
     */
    private $customerSetupFactory;

    /**
     * UpgradeData constructor.
     * @param EavSetupFactory $eavSetup
     * @param \Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory
     */
    public function __construct(
        EavSetupFactory $eavSetup,
        CustomerSetupFactory $customerSetupFactory
    ) {
        $this->eavSetupFactory = $eavSetup;
        $this->customerSetupFactory = $customerSetupFactory;
    }

    /**
     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Zend_Validate_Exception
     */
    public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;

        $installer->getConnection()->startSetup();
        if (version_compare($context->getVersion(), '1.0.1', '<')) {
            $this->upgradeGeoData($installer);
        }

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

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

        if (version_compare($context->getVersion(), '1.0.17', '<')) {
            $this->upgradeProductRefiloTemplateAttribute($installer);
            $this->upgradeCategoryRefiloTemplateAttribute($installer);
        }

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

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

        if (version_compare($context->getVersion(), '1.0.20', '<')) {
            $this->upgradeCategoryHideFiltersAttribute($installer);
            $this->upgradeCategoryHideSortbyAttribute($installer);
            $this->upgradeCategoryTitleVariantAttribute($installer);
        }

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

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

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

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

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

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

        $installer->getConnection()->endSetup();
    }

    /**
     * @param ModuleDataSetupInterface $installer
     */
    public function upgradeGeoData(ModuleDataSetupInterface $installer)
    {
        $countryContinentTableName = $installer->getTable('filoblu_refilo_country_continent');
        $continentTableName = $installer->getTable('filoblu_refilo_continent');

        $countryContinentData = json_decode(file_get_contents($this->getFilePath('country_continent.json')), true);
        $continentData = json_decode(file_get_contents($this->getFilePath('continent.json')), true);

        foreach ($countryContinentData as $item) {
            $installer->getConnection()->insert($countryContinentTableName, $item);
        }

        foreach ($continentData as $item) {
            $installer->getConnection()->insert($continentTableName, $item);
        }
    }

    /**
     * @param $filename
     * @return string
     */
    public function getFilePath($filename)
    {
        return implode(
            DIRECTORY_SEPARATOR, [__DIR__, '..', 'Files', $filename]
        );
    }

    /**
     * @param ModuleDataSetupInterface $installer
     */
    public function upgradeCountryTranslations(ModuleDataSetupInterface $installer)
    {
        $translationTable = $installer->getTable('translation');

        $localeList = ['en_US', 'it_IT', 'fr_FR', 'de_DE', 'es_ES', 'zh_CN', 'ru_RU', 'ja_JP'];

        foreach ($localeList as $locale) {
            $list = Zend_Locale::getTranslationList('territory', $locale, 2);
            foreach ($list as $countryCode => $translation) {
                $item = [
                    'string'    => "country_$countryCode",
                    'store_id'  => 0,
                    'translate' => $translation,
                    'locale'    => $locale
                ];
                $installer->getConnection()->insert($translationTable, $item);
            }
        }
    }

    /**
     * @param ModuleDataSetupInterface $installer
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Zend_Validate_Exception
     */
    private function upgradeContentAttribute(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);

        if (!$eavSetup->getAttribute(Product::ENTITY, 'content_block_identifier')) {
            $eavSetup->addAttribute(Content::ENTITY, 'content_block_identifier', [
                'type'         => 'varchar',
                'label'        => 'Content Block Identifier',
                'visible'      => true,
                'required'     => false,
                'user_defined' => false,
                'searchable'   => true,
                'filterable'   => true,
                'comparable'   => false,
                'is_global'    => true,
                'global'       => ScopedAttributeInterface::SCOPE_STORE,
            ]);
        }
    }

    /**
     * @param ModuleDataSetupInterface $installer
     * @throws LocalizedException
     * @throws \Zend_Validate_Exception
     */
    private function upgradeCategoryAttributes(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Product::ENTITY, 'refilo_exclude_from_search')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_exclude_from_search', [
                    'type'                  => 'int',
                    'label'                 => 'Excluded from search',
                    'input'                 => 'select',
                    'source'                => Boolean::class,
                    'required'              => false,
                    'sort_order'            => 51,
                    'backend'               => Product\Attribute\Backend\Boolean::class,
                    'global'                => ScopedAttributeInterface::SCOPE_STORE,
                    'group'                 => 'General',
                    'visible'               => true,
                    'is_used_in_grid'       => true,
                    'is_visible_in_grid'    => true,
                    'is_filterable_in_grid' => true,
                    'is_searchable_in_grid' => true
                ]

            );
        }
    }

    /**
     * @param ModuleDataSetupInterface $installer
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Zend_Validate_Exception
     */
    private function upgradeProductRefiloTemplateAttribute(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Product::ENTITY, 'refilo_template')) {
            $eavSetup->addAttribute(
                Product::ENTITY, 'refilo_template', [
                    'type'                    => 'text',
                    'backend'                 => '',
                    'frontend'                => '',
                    'label'                   => 'Refilo Template',
                    'input'                   => 'text',
                    'class'                   => '',
                    'source'                  => '',
                    'global'                  => ScopedAttributeInterface::SCOPE_STORE,
                    'visible'                 => true,
                    'required'                => false,
                    'user_defined'            => false,
                    'default'                 => '',
                    'searchable'              => true,
                    'filterable'              => false,
                    'comparable'              => false,
                    'visible_on_front'        => true,
                    'used_in_product_listing' => true,
                    'unique'                  => false,
                    'apply_to'                => ''
                ]

            );
        }
    }

    /**
     * @param ModuleDataSetupInterface $installer
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Zend_Validate_Exception
     */
    private function upgradeCategoryRefiloTemplateAttribute(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Product::ENTITY, 'refilo_template')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_template', [
                    'type'         => 'varchar',
                    'label'        => 'Refilo Template',
                    'input'        => 'text',
                    'sort_order'   => 61,
                    'source'       => '',
                    'visible'      => true,
                    'required'     => false,
                    'user_defined' => false,
                    'searchable'   => false,
                    'filterable'   => false,
                    'comparable'   => false,
                    'is_global'    => true,
                    'global'       => ScopedAttributeInterface::SCOPE_STORE,
                    'group'        => 'General',
                    'backend'      => ''
                ]

            );
        }
    }

    /**
     * @param ModuleDataSetupInterface $installer
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Zend_Validate_Exception
     */
    private function upgradeCategoryMobileImageAttribute(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);

        if (!$eavSetup->getAttribute(Product::ENTITY, 'mobile_image')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'mobile_image', [
                    'type'         => 'varchar',
                    'label'        => 'Mobile Image',
                    'input'        => 'image',
                    'backend'      => Image::class,
                    'sort_order'   => 6,
                    'source'       => '',
                    'visible'      => true,
                    'required'     => false,
                    'user_defined' => false,
                    'searchable'   => true,
                    'filterable'   => true,
                    'comparable'   => false,
                    'is_global'    => true,
                    'global'       => ScopedAttributeInterface::SCOPE_STORE,
                    'group'        => 'General Information',
                ]

            );
        }
    }

    /**
     * @param \Magento\Framework\Setup\ModuleDataSetupInterface $setup
     * @return void
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Zend_Validate_Exception
     */
    public function addDisableShopMissingAttributes(ModuleDataSetupInterface $setup)
    {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        if (!$eavSetup->getAttribute(Product::ENTITY, 'disable_shop')) {
            $eavSetup->addAttribute(
                Product::ENTITY, 'disable_shop',/* Custom Attribute Code */ [
                    'group'                   => 'Product Details',
                    'type'                    => 'int',
                    'backend'                 => '',
                    'frontend'                => '',
                    'label'                   => 'Disable Shop',
                    'input'                   => 'boolean',
                    'class'                   => '',
                    'source'                  => Boolean::class,
                    'global'                  => ScopedAttributeInterface::SCOPE_WEBSITE,
                    'visible'                 => true,
                    'required'                => false,
                    'user_defined'            => false,
                    'default'                 => '0',
                    'searchable'              => false,
                    'filterable'              => false,
                    'comparable'              => false,
                    'visible_on_front'        => false,
                    'used_in_product_listing' => true,
                    'unique'                  => false
                ]
            );
        }
        if (!$eavSetup->getAttribute(Product::ENTITY, 'hide_price')) {
            $eavSetup->addAttribute(
                Product::ENTITY, 'hide_price', [
                    'group'                   => 'Product Details',
                    'type'                    => 'int',
                    'backend'                 => '',
                    'frontend'                => '',
                    'label'                   => 'Hide Price',
                    'input'                   => 'boolean',
                    'class'                   => '',
                    'source'                  => Boolean::class,
                    'global'                  => ScopedAttributeInterface::SCOPE_WEBSITE,
                    'visible'                 => true,
                    'required'                => false,
                    'user_defined'            => false,
                    'default'                 => '0',
                    'searchable'              => false,
                    'filterable'              => false,
                    'comparable'              => false,
                    'visible_on_front'        => false,
                    'used_in_product_listing' => true,
                    'unique'                  => false
                ]
            );
        }
    }

    /**
     * @param ModuleDataSetupInterface $installer
     * @return void
     * @throws LocalizedException
     * @throws \Zend_Validate_Exception
     */
    private function upgradeCategoryHideFiltersAttribute(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Category::ENTITY, 'refilo_hide_filters')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_hide_filters', [
                    'type'                  => 'int',
                    'label'                 => 'Hide Filters',
                    'input'                 => 'select',
                    'source'                => Boolean::class,
                    'required'              => false,
                    'sort_order'            => 70,
                    'backend'               => Product\Attribute\Backend\Boolean::class,
                    'global'                => ScopedAttributeInterface::SCOPE_STORE,
                    'group'                 => 'General',
                    'visible'               => true,
                    'is_used_in_grid'       => true,
                    'is_visible_in_grid'    => true,
                    'is_filterable_in_grid' => true,
                    'is_searchable_in_grid' => true,
                    'default'               => '0'
                ]

            );
        }
    }

    /**
     * @param ModuleDataSetupInterface $installer
     * @return void
     * @throws LocalizedException
     * @throws \Zend_Validate_Exception
     */
    private function upgradeCategoryHideSortbyAttribute(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Category::ENTITY, 'refilo_hide_sortby')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_hide_sortby', [
                    'type'                  => 'int',
                    'label'                 => 'Hide Sortby',
                    'input'                 => 'select',
                    'source'                => Boolean::class,
                    'required'              => false,
                    'sort_order'            => 71,
                    'backend'               => Product\Attribute\Backend\Boolean::class,
                    'global'                => ScopedAttributeInterface::SCOPE_STORE,
                    'group'                 => 'General',
                    'visible'               => true,
                    'is_used_in_grid'       => true,
                    'is_visible_in_grid'    => true,
                    'is_filterable_in_grid' => true,
                    'is_searchable_in_grid' => true,
                    'default'               => '0'
                ]

            );
        }
    }

    /**
     * @param ModuleDataSetupInterface $installer
     * @throws LocalizedException
     * @throws \Zend_Validate_Exception
     */
    private function upgradeCategoryTitleVariantAttribute(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Category::ENTITY, 'refilo_tile_variant')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_tile_variant', [
                    'type'         => 'varchar',
                    'label'        => 'Tile Variant',
                    'input'        => 'text',
                    'sort_order'   => 72,
                    'source'       => '',
                    'visible'      => true,
                    'required'     => false,
                    'user_defined' => false,
                    'searchable'   => false,
                    'filterable'   => false,
                    'comparable'   => false,
                    'is_global'    => true,
                    'global'       => ScopedAttributeInterface::SCOPE_STORE,
                    'group'        => 'General',
                    'backend'      => ''
                ]

            );
        }
    }

    /**
     * @param \Magento\Framework\Setup\ModuleDataSetupInterface $installer
     * @return void
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Zend_Validate_Exception
     */
    private function upgradeCategoryHeadingVariantAttribute(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Category::ENTITY, 'refilo_heading_variant')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_heading_variant', [
                    'type'         => 'varchar',
                    'label'        => 'Header Variant',
                    'input'        => 'text',
                    'sort_order'   => 75,
                    'source'       => '',
                    'visible'      => true,
                    'required'     => false,
                    'user_defined' => false,
                    'searchable'   => false,
                    'filterable'   => false,
                    'comparable'   => false,
                    'is_global'    => true,
                    'global'       => ScopedAttributeInterface::SCOPE_STORE,
                    'group'        => 'General',
                    'backend'      => ''
                ]
            );
        }
    }

    /**
     * @throws Zend_Validate_Exception
     * @throws LocalizedException
     */
    private function upgradeCategoryIdentifier(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Category::ENTITY, 'refilo_category_identifier')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_category_identifier', [
                    'type'         => 'varchar',
                    'label'        => 'Refilo Category Identifier',
                    'input'        => 'text',
                    'sort_order'   => 76,
                    'source'       => '',
                    'visible'      => true,
                    'required'     => false,
                    'user_defined' => false,
                    'searchable'   => false,
                    'filterable'   => false,
                    'comparable'   => false,
                    'is_global'    => false,
                    'global'       => ScopedAttributeInterface::SCOPE_STORE,
                    'group'        => 'General',
                    'backend'      => ''
                ]
            );
        }
    }

    private function upgradeCategoryViewMode(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Category::ENTITY, 'refilo_view_mode_enabled')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_view_mode_enabled', [
                    'type'                  => 'int',
                    'label'                 => 'View Mode Enabled',
                    'input'                 => 'select',
                    'source'                => Boolean::class,
                    'required'              => false,
                    'sort_order'            => 76,
                    'backend'               => Product\Attribute\Backend\Boolean::class,
                    'global'                => ScopedAttributeInterface::SCOPE_STORE,
                    'group'                 => 'General',
                    'visible'               => true,
                    'is_used_in_grid'       => true,
                    'is_visible_in_grid'    => true,
                    'is_filterable_in_grid' => true,
                    'is_searchable_in_grid' => true,
                    'default'               => '0'
                ]
            );
        }
        if (!$eavSetup->getAttribute(Category::ENTITY, 'refilo_view_mode')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_view_mode', [
                    'type'         => 'varchar',
                    'label'        => 'View Mode',
                    'input'        => 'text',
                    'sort_order'   => 77,
                    'source'       => '',
                    'visible'      => true,
                    'required'     => false,
                    'user_defined' => false,
                    'searchable'   => false,
                    'filterable'   => false,
                    'comparable'   => false,
                    'is_global'    => true,
                    'global'       => ScopedAttributeInterface::SCOPE_STORE,
                    'group'        => 'General',
                    'backend'      => ''
                ]
            );
        }
    }

    private function addCareofField(ModuleDataSetupInterface $installer)
    {
        $customerSetup = $this->customerSetupFactory->create(['setup' => $installer]);
        $customerSetup->addAttribute('customer_address', 'care_of', [
            'label'                 => 'Care of',
            'input'                 => 'text',
            'type'                  => Table::TYPE_TEXT,
            'source'                => '',
            'required'              => false,
            'position'              => 75,
            'visible'               => true,
            'system'                => false,
            'is_used_in_grid'       => true,
            'is_visible_in_grid'    => true,
            'is_filterable_in_grid' => true,
            'is_searchable_in_grid' => true,
            'backend'               => ''
        ]);

        $attribute = $customerSetup->getEavConfig()->getAttribute('customer_address', 'care_of')->addData([
                'used_in_forms' => [
                    'adminhtml_customer_address',
                    'adminhtml_customer',
                    'customer_address_edit',
                    'customer_register_address',
                    'customer_address',
                ]
            ]);
        $attribute->save();
    }

    private function upgradeChildrenCategoriesEnabled(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Category::ENTITY, 'refilo_children_categories_enabled')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_children_categories_enabled', [
                    'type'                  => 'int',
                    'label'                 => 'Children Categories Enabled',
                    'input'                 => 'select',
                    'source'                => Boolean::class,
                    'required'              => false,
                    'sort_order'            => 76,
                    'backend'               => Product\Attribute\Backend\Boolean::class,
                    'global'                => ScopedAttributeInterface::SCOPE_STORE,
                    'group'                 => 'General',
                    'visible'               => true,
                    'is_used_in_grid'       => true,
                    'is_visible_in_grid'    => true,
                    'is_filterable_in_grid' => true,
                    'is_searchable_in_grid' => true,
                    'default'               => '1'
                ]
            );
        }
        if (!$eavSetup->getAttribute(Category::ENTITY, 'refilo_siblings_categories_enabled')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'refilo_siblings_categories_enabled', [
                    'type'                  => 'int',
                    'label'                 => 'Siblings Categories Enabled',
                    'input'                 => 'select',
                    'source'                => Boolean::class,
                    'required'              => false,
                    'sort_order'            => 76,
                    'backend'               => Product\Attribute\Backend\Boolean::class,
                    'global'                => ScopedAttributeInterface::SCOPE_STORE,
                    'group'                 => 'General',
                    'visible'               => true,
                    'is_used_in_grid'       => true,
                    'is_visible_in_grid'    => true,
                    'is_filterable_in_grid' => true,
                    'is_searchable_in_grid' => true,
                    'default'               => '1'
                ]
            );
        }
    }

    /**
     * @param ModuleDataSetupInterface $installer
     * @return void
     * @throws LocalizedException
     * @throws Zend_Validate_Exception
     */
    private function addEmotionalProductsAttribute(ModuleDataSetupInterface $installer)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $installer]);
        if (!$eavSetup->getAttribute(Category::ENTITY, 'emotional_products')) {
            $eavSetup->addAttribute(
                Category::ENTITY, 'emotional_products', [
                    'type'         => Table::TYPE_TEXT,
                    'input'        => 'text',
                    'label'        => 'Emotional Products',
                    'sort_order'   => 77,
                    'source'       => '',
                    'visible'      => true,
                    'required'     => false,
                    'user_defined' => false,
                    'searchable'   => false,
                    'filterable'   => false,
                    'comparable'   => false,
                    'is_global'    => true,
                    'global'       => ScopedAttributeInterface::SCOPE_STORE,
                    'group'        => 'General',
                    'backend'      => ''
                ]
            );
        }
    }
}
