<?php
/**
 * @author 1902 Software
 * @copyright Copyright © 2023 1902 Software (https://1902software.com/magento/)
 * @package WriteTextAI_WriteTextAI
 */

namespace WriteTextAI\WriteTextAI\Setup\Patch\Data;

use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Authorization\Model\RoleFactory;
use Magento\Authorization\Model\RulesFactory;
use Magento\Authorization\Model\UserContextInterface;
use Magento\Authorization\Model\Acl\Role\Group as RoleGroup;
use Magento\Authorization\Model\ResourceModel\Role\CollectionFactory as RoleCollectionFactory;

class UserRoles implements DataPatchInterface
{
    public const ADMIN_ROLE = 'WriteText.ai Administrator';

    public const EDITOR_ROLE = 'WriteText.ai Editor';

    public const CONTRIBUTOR_ROLE = 'WriteText.ai Contributor';

    /**
     * @var ModuleDataSetupInterface
     */
    protected $moduleDataSetup;

    /**
     * @var RoleFactory
     */
    protected $roleFactory;

    /**
     * @var RulesFactory
     */
    protected $rulesFactory;

    /**
     * @var RoleCollectionFactory
     */
    protected $roleCollectionFactory;

    /**
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param RoleFactory $roleFactory
     * @param RulesFactory $rulesFactory
     * @param RoleCollectionFactory $roleCollectionFactory
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        RoleFactory $roleFactory,
        RulesFactory $rulesFactory,
        RoleCollectionFactory $roleCollectionFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->roleFactory = $roleFactory;
        $this->rulesFactory = $rulesFactory;
        $this->roleCollectionFactory = $roleCollectionFactory;
    }

    /**
     * @inheritdoc
     */
    public function apply()
    {
        $this->moduleDataSetup->getConnection()->startSetup();
        $this->createWriteTextAdmin();
        $this->createWriteTextEditor();
        $this->createWriteTextContributor();
        $this->moduleDataSetup->getConnection()->endSetup();
    }

    /**
     * @inheritdoc
     */
    public static function getDependencies()
    {
        return [];
    }

    /**
     * @inheritdoc
     */
    public function getAliases()
    {
        return [];
    }

    /**
     * Check if role exists by name
     *
     * @param string $roleName
     * @return bool
     */
    private function roleExists(string $roleName): bool
    {
        $roleCollection = $this->roleCollectionFactory->create();
        $roleCollection->addFieldToFilter('role_name', $roleName);
        return $roleCollection->getSize() > 0;
    }

    /**
     * Create WriteText.ai Administrator Role
     *
     * @return void
     */
    private function createWriteTextAdmin()
    {
        if ($this->roleExists(self::ADMIN_ROLE)) {
            return;
        }

        $role = $this->roleFactory->create();
        $role->setName(self::ADMIN_ROLE)
            ->setPid(0)
            ->setRoleType(RoleGroup::ROLE_TYPE)
            ->setUserType(UserContextInterface::USER_TYPE_ADMIN);
        $role->save();

        $resource = [
            'WriteTextAI_WriteTextAI::menu',
            'WriteTextAI_WriteTextAI::transfer',
            'WriteTextAI_WriteTextAI::review',
            'WriteTextAI_WriteTextAI::edit',
            'WriteTextAI_WriteTextAI::product_details',
            'WriteTextAI_WriteTextAI::modify_defaults',
            'WriteTextAI_WriteTextAI::modify_attributes',
            'WriteTextAI_WriteTextAI::modify_tone_style',
            'WriteTextAI_WriteTextAI::modify_words',
            'WriteTextAI_WriteTextAI::generate'
        ];

        $this->rulesFactory->create()
            ->setRoleId($role->getId())
            ->setResources($resource)
            ->saveRel();
    }

    /**
     * Create WriteText.ai Editor Role
     *
     * @return void
     */
    private function createWriteTextEditor()
    {
        if ($this->roleExists(self::EDITOR_ROLE)) {
            return;
        }

        $role = $this->roleFactory->create();
        $role->setName(self::EDITOR_ROLE)
            ->setPid(0)
            ->setRoleType(RoleGroup::ROLE_TYPE)
            ->setUserType(UserContextInterface::USER_TYPE_ADMIN);
        $role->save();

        $resource = [
            'WriteTextAI_WriteTextAI::menu',
            'WriteTextAI_WriteTextAI::transfer',
            'WriteTextAI_WriteTextAI::review',
            'WriteTextAI_WriteTextAI::edit',
            'WriteTextAI_WriteTextAI::product_details',
            'WriteTextAI_WriteTextAI::modify_attributes',
            'WriteTextAI_WriteTextAI::modify_tone_style',
            'WriteTextAI_WriteTextAI::modify_words',
            'WriteTextAI_WriteTextAI::generate'
        ];

        $this->rulesFactory->create()
            ->setRoleId($role->getId())
            ->setResources($resource)
            ->saveRel();
    }

    /**
     * Create WriteText.ai Contributor Role
     *
     * @return void
     */
    private function createWriteTextContributor()
    {
        if ($this->roleExists(self::CONTRIBUTOR_ROLE)) {
            return;
        }

        $role = $this->roleFactory->create();
        $role->setName(self::CONTRIBUTOR_ROLE)
            ->setPid(0)
            ->setRoleType(RoleGroup::ROLE_TYPE)
            ->setUserType(UserContextInterface::USER_TYPE_ADMIN);
        $role->save();

        $resource = [
            'WriteTextAI_WriteTextAI::menu',
            'WriteTextAI_WriteTextAI::edit',
            'WriteTextAI_WriteTextAI::product_details',
            'WriteTextAI_WriteTextAI::modify_attributes',
            'WriteTextAI_WriteTextAI::modify_tone_style',
            'WriteTextAI_WriteTextAI::modify_words',
            'WriteTextAI_WriteTextAI::generate'
        ];

        $this->rulesFactory->create()
            ->setRoleId($role->getId())
            ->setResources($resource)
            ->saveRel();
    }
}
