<?php

namespace Webuccino\Install\Core;

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Capsule\Manager as DB;

class Migration
{
    public $migrations;
    public $db;
    public $prefix;
    public function __construct()
    {
        $this->migrations = [
            'Webuccino\Install\migrations\CreateGroupsTable',
            'Webuccino\Install\migrations\CreateUsersTable',
            'Webuccino\Install\migrations\CreateInstalledVersionsTable',
            'Webuccino\Install\migrations\CreateMailTable',
            'Webuccino\Install\migrations\CreateOrganizationTable',
            'Webuccino\Install\migrations\CreatePasswordResetTokensTable',
            'Webuccino\Install\migrations\CreateSettingsTable',
            'Webuccino\Install\migrations\CreateSessionsTable',
            'Webuccino\Install\migrations\CreateModulesTable',
            'Webuccino\Install\migrations\CreateCategoriesTable',
            'Webuccino\Install\migrations\CreateDataConnectionsTable',
            'Webuccino\Install\migrations\CreateAnalyticsResourcesTable',
            'Webuccino\Install\migrations\CreateResourcePermissionsTable',
            'Webuccino\Install\migrations\CreateModulesPermissionsTable',
            'Webuccino\Install\migrations\CreateResourceConfigurationTable',
            'Webuccino\Install\migrations\CreateScheduledTasksTable',
            'Webuccino\Install\migrations\CreateScheduledTaskGroupsTable',
            'Webuccino\Install\migrations\CreateScheduledTaskResourcesTable',
            'Webuccino\Install\migrations\CreateScheduledTaskHistoryTable',
            'Webuccino\Install\migrations\CreateScheduledTasksSendingLogTable',
            'Webuccino\Install\migrations\CreateJobsTable',
            'Webuccino\Install\migrations\CreateFailedJobsTable',
            'Webuccino\Install\migrations\CreateHomeDashboardTable',
            'Webuccino\Install\migrations\CreateDashboardsTable',
            'Webuccino\Install\migrations\CreateWidgetsTable',
        ];

        if (!is_docker() ||
            (!is_null(getenv('ADD_TESTING_DATA')) && getenv('ADD_TESTING_DATA') == 'true')
        ) {
            $this->migrations[] = 'Webuccino\Install\migrations\CreateNorthWindTables';
        }

        App::resolve('Webuccino\Install\Core\Database')->initiateConnectionFromconfig_native();

        $this->db = new DB();

        $this->prefix = config_native('srm_config.installer.table_prefix');
    }

    public function migrateMigrationsTable()
    {

        if (!DB::schema()->hasTable($this->prefix . 'migrations')) {
            (new \Webuccino\Install\migrations\CreateMigrationsTable())->run();
        }

    }

    public function runMigrations()
    {
        $this->migrateMigrationsTable();

        $lastBatch = $this->getLastBatch() + 1;

        foreach ($this->migrations as $migration) {

            if ($this->checkMigrationExists($migration) && $this->checkTableNamesExists($migration)) {
                continue;
            } elseif (!$this->checkMigrationExists($migration) && $this->checkTableNamesExists($migration)) {
                throw new \Exception('Tables with same names already exists in your database! Please choose another database.');
            }

            (new $migration())->run();

            $this->db->table($this->prefix . 'migrations')->insert([
                'migration' => $this->getMigrationName($migration),
                'batch'     => $lastBatch,
            ]);
        }

    }

    public function getMigrationName($migration)
    {
        $migration_path = explode("\\", $migration);
        return $migration_path[sizeof($migration_path) - 1];
    }

    public function getTableName($migration)
    {
        return (new $migration())->getTableName();
    }

    public function checkMigrationExists($migration)
    {
        $table = $this->getMigrationName($migration);

        return $this->db->table($this->prefix . 'migrations')
            ->where('migration', $table)
            ->exists();
    }

    public function getLastBatch()
    {

        if ($this->db->table($this->prefix . 'migrations')->exists()) {
            return $this->db->table($this->prefix . 'migrations')
                ->latest('created_at')->batch;
        } else {
            return 0;
        }

    }

    public function checkTableNamesExists($table)
    {
        return DB::schema()
            ->hasTable($this->getTableName($table));
    }

}
