<?php
namespace App\Services;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Artisan;
use App\Models\User;
use App\Database\Migrations\MasterMigration;
use App\Database\Migrations\TenantMigration;

class MigrationService
{
    protected $masterDatabase = 'easia_master';

    public function runMasterMigrations()
    {
        
        $this->setupMasterConnection();

        $masterMigrations = $this->getMasterMigrationFiles();

        if (empty($masterMigrations)) {
            return ['message' => 'No master migrations found.', 'migrations' => []];
        }

        // Create a temporary directory for master migrations only
        $tempPath = storage_path('app/temp_master_migrations');
        if (!File::exists($tempPath)) {
            File::makeDirectory($tempPath, 0755, true);
        }

        // Copy only master migrations to temp directory
        foreach ($masterMigrations as $migration) {
            $source = database_path('migrations/' . $migration);
            $destination = $tempPath . '/' . $migration;
            File::copy($source, $destination);
        }

        try {
            // Run migrations from temp directory
            Artisan::call('migrate', [
                '--database' => 'master',
                '--path' => 'storage/app/temp_master_migrations'
            ]);

            $output = Artisan::output();
        } finally {
            // Clean up temp directory
            File::deleteDirectory($tempPath);
        }

        return [
            'message' => 'Master migrations completed successfully!',
            'database' => $this->masterDatabase,
            'migrations' => $masterMigrations,
            'output' => $output
        ];
    }

    public function runTenantMigrations()
    {
        $tenants = $this->getTenants();
        $results = [];

        if ($tenants->isEmpty()) {
            return ['message' => 'No tenants found.', 'results' => []];
        }

        $tenantMigrations = $this->getTenantMigrationFiles();

        if (empty($tenantMigrations)) {
            return ['message' => 'No tenant migrations found.', 'results' => []];
        }

        // Create a temporary directory for tenant migrations only
        $tempPath = storage_path('app/temp_tenant_migrations');
        if (!File::exists($tempPath)) {
            File::makeDirectory($tempPath, 0755, true);
        }

        // Copy only tenant migrations to temp directory
        foreach ($tenantMigrations as $migration) {
            $source = database_path('migrations/' . $migration);
            $destination = $tempPath . '/' . $migration;
            File::copy($source, $destination);
        }

        foreach ($tenants as $tenant) {
            try {
                $this->setupTenantConnection($tenant);

                Artisan::call('migrate', [
                    '--database' => 'tenant',
                    '--path' => 'storage/app/temp_tenant_migrations'
                ]);

                $results[] = [
                    'tenant' => $tenant->tenant_database,
                    'status' => 'success',
                    'message' => 'Migrations completed successfully'
                ];

            } catch (\Exception $e) {
                $results[] = [
                    'tenant' => $tenant->tenant_database,
                    'status' => 'error',
                    'message' => $e->getMessage()
                ];
            }
        }

        // Clean up temp directory
        File::deleteDirectory($tempPath);

        return [
            'message' => 'Tenant migrations process completed',
            'results' => $results
        ];
    }

    public function rollbackMasterMigrations($steps = 1)
    {
        $this->setupMasterConnection();

        Artisan::call('migrate:rollback', [
            '--database' => 'master',
            '--step' => $steps
        ]);

        return [
            'message' => "Master database rolled back {$steps} step(s)",
            'database' => $this->masterDatabase,
            'output' => Artisan::output()
        ];
    }

    public function rollbackTenantMigrations($steps = 1)
    {
        $tenants = $this->getTenants();
        $results = [];

        foreach ($tenants as $tenant) {
            try {
                $this->setupTenantConnection($tenant);

                Artisan::call('migrate:rollback', [
                    '--database' => 'tenant',
                    '--step' => $steps
                ]);

                $results[] = [
                    'tenant' => $tenant->tenant_database,
                    'status' => 'success',
                    'message' => "Rolled back {$steps} step(s)"
                ];

            } catch (\Exception $e) {
                $results[] = [
                    'tenant' => $tenant->tenant_database,
                    'status' => 'error',
                    'message' => $e->getMessage()
                ];
            }
        }

        return [
            'message' => 'Tenant rollback process completed',
            'results' => $results
        ];
    }

    protected function setupMasterConnection()
    {
        config(['database.connections.master' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => $this->masterDatabase,
            'username' => env('DB_USERNAME'),
            'password' => env('DB_PASSWORD'),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ]]);

        config(['database.default' => 'master']);
        DB::purge('master');
        DB::reconnect('master');
    }

    protected function setupTenantConnection($tenant)
    {
        config(['database.connections.tenant' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => $tenant->tenant_database,
            'username' => $tenant->tenant_username,
            'password' => $tenant->tenant_password,
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ]]);

        config(['database.default' => 'tenant']);
        DB::purge('tenant');
        DB::reconnect('tenant');
    }

    protected function getTenants()
    {
        return User::select('tenant_database', 'tenant_username', 'tenant_password')
            ->whereNotNull('tenant_database')
            ->distinct()
            ->get();
    }

    protected function getMasterMigrationFiles()
    {
        $migrationPath = database_path('migrations');
        $files = File::glob($migrationPath . '/*.php');
        $masterMigrations = [];

        foreach ($files as $file) {
            $content = File::get($file);
            if (strpos($content, 'extends MasterMigration') !== false) {
                $masterMigrations[] = basename($file);
            }
        }

        return $masterMigrations;
    }

    protected function getTenantMigrationFiles()
    {
        $migrationPath = database_path('migrations');
        $files = File::glob($migrationPath . '/*.php');
        $tenantMigrations = [];

        foreach ($files as $file) {
            $content = File::get($file);
            if (strpos($content, 'extends TenantMigration') !== false) {
                $tenantMigrations[] = basename($file);
            }
        }

        return $tenantMigrations;
    }
}
