<?php

namespace core\services;

use core\components\SearchPerformance;
use core\entities\ModuleRecord;
use core\repositories\ModuleRepository;
use yii\helpers\FileHelper;
use Yii;

class ModuleService
{
    private $_modules;
    private $_permission_manager;

    public function __construct(ModuleRepository $modules, PermissionManager $permission_manager)
    {
        $this->_modules            = $modules;
        $this->_permission_manager = $permission_manager;
    }

    public function create($name, $class, $type = 'common', $active = ModuleRecord::STATUS_DISABLED): ModuleRecord
    {
        $module         = new ModuleRecord();
        $module->name   = $name;
        $module->class  = $class;
        $module->type   = $type;
        $module->active = $active;
        $this->_modules->save($module);

        return $module;
    }

    /**
     * @param ModuleRecord $module
     *
     * @throws \yii\base\ErrorException
     */
    public function delete(ModuleRecord $module)
    {
        // connect manifest
        $manifest = require Yii::getAlias('@common/modules/' . $module->name . '/manifest.php');

        // down migrations
        $migrations = $this->getMigrationFiles($module->name);
        $migrations = array_reverse($migrations);
        foreach ($migrations as $migrationPath) {
            $migrationFile = basename($migrationPath);
            $migration     = str_replace('.php', '', $migrationFile);
            if ($this->migrationExists($migration)) {
                require $migrationPath;
                $obj = new $migration;
                if (method_exists($obj, 'safeDown')) {
                    $obj->safeDown();
                    Yii::$app->moduleManager->removeFromMigrationTable($migration);
                } elseif (method_exists($obj, 'down')) {
                    $obj->down();
                    Yii::$app->moduleManager->removeFromMigrationTable($migration);
                }
            }
        }

        // remove permissions
        if (isset($manifest['permissions']) && is_array($manifest['permissions'])) {
            $this->removePermissions($manifest['permissions']);
        }

        // delete files
        $modulePath = Yii::getAlias('@common/modules/' . $module->name);
        if (file_exists($modulePath)) {
            FileHelper::removeDirectory($modulePath);
        }
        // delete module record
        $this->_modules->remove($module);
    }

    public function disable(ModuleRecord $module)
    {
        $module->active = ModuleRecord::STATUS_DISABLED;
        $this->_modules->save($module);
        // regenerate global control panel search
        SearchPerformance::init();
    }

    public function enable(ModuleRecord $module)
    {
        $module->active = ModuleRecord::STATUS_ENABLED;
        $this->_modules->save($module);
        // regenerate global control panel search
        SearchPerformance::init();
    }

    public function setSystem(ModuleRecord $module)
    {
        $module->system = ModuleRecord::SYSTEM_YES;
        $this->_modules->save($module);
    }

    private function getMigrationFiles($module)
    {
        // migration if not exists
        $migrationPath = Yii::getAlias('@common/modules/' . $module . '/migrations');

        return file_exists($migrationPath) ? FileHelper::findFiles($migrationPath) : [];
    }

    private function migrationExists($name): bool
    {
        // check record exists
        $connection = Yii::$app->getDb();
        $command    = $connection->createCommand("SELECT * FROM migration WHERE version = '$name'");
        $result     = $command->queryAll();

        return $result ? true : false;
    }
}