<?php

namespace App\Console\Commands;

use App\OldDataMigrations\BaseOldDataMigration;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\DB;
use Spatie\Permission\PermissionRegistrar;

class MigrateOldDataCommand extends Command
{
    protected $signature = 'app:migrate-old-data {--only=} {--skip=} {--force}';

    protected $description = 'Migrate data from old database to new database';

    public function handle(): int
    {
        $filesystem = new Filesystem;
        $migrationPath = app_path('OldDataMigrations');

        require_once $migrationPath.'/BaseOldDataMigration.php';

        $files = collect($filesystem->glob($migrationPath.'/*.php'))
            ->map(fn ($file) => basename($file))
            ->filter(fn ($file) => $file !== 'BaseOldDataMigration.php')
            ->toArray();

        $migrations = [];

        foreach ($files as $file) {
            require_once $migrationPath.'/'.$file;

            $className = 'App\\OldDataMigrations\\'.str_replace('.php', '', $file);

            if (! class_exists($className)) {
                continue;
            }

            $instance = new $className;

            if ($instance instanceof BaseOldDataMigration) {
                $migrations[] = $instance;
            }
        }

        usort($migrations, fn ($a, $b) => $a->priority() <=> $b->priority());

        $only = $this->option('only') ? explode(',', $this->option('only')) : null;
        $skip = $this->option('skip') ? explode(',', $this->option('skip')) : [];
        BaseOldDataMigration::$truncateBeforeInsert = $this->option('force');

        $this->newLine();
        $this->info('=== Migrate Old Data ===');
        $this->newLine();

        DB::connection('mysql')->getPdo()->exec('SET FOREIGN_KEY_CHECKS=0');
        $this->warn('Foreign key checks disabled.');

        app(PermissionRegistrar::class)->forgetCachedPermissions();

        $totalRows = 0;
        $tableSummary = [];

        foreach ($migrations as $migration) {
            if ($only !== null) {
                $results = $migration->migrate();
                $groupTableNames = array_keys($results);
                $hasOverlap = false;
                foreach ($only as $t) {
                    if (in_array($t, $groupTableNames)) {
                        $hasOverlap = true;
                        break;
                    }
                }
                if (! $hasOverlap) {
                    continue;
                }
            }

            $className = (new \ReflectionClass($migration))->getShortName();
            $this->info("Running: {$className}");

            $results = $migration->migrate();

            foreach ($results as $table => $count) {
                if (in_array($table, $skip)) {
                    $this->line("  SKIP  {$table}");

                    continue;
                }

                $tableSummary[$table] = $count;
                $totalRows += $count;
                $this->line("  OK    {$table}: {$count} rows");
            }

            $this->newLine();
        }

        DB::connection('mysql')->getPdo()->exec('SET FOREIGN_KEY_CHECKS=1');
        app(PermissionRegistrar::class)->forgetCachedPermissions();
        $this->warn('Foreign key checks re-enabled.');

        $this->newLine();
        $this->info('=== Summary ===');
        $this->info('Total tables: '.count($tableSummary));
        $this->info("Total rows: {$totalRows}");
        $this->newLine();

        $this->table(['Table', 'Rows'], collect($tableSummary)->map(fn ($count, $table) => [$table, $count])->values()->toArray());

        return Command::SUCCESS;
    }
}
