<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class FlagLegacyUsersForMigrationCommand extends Command
{
    protected $signature = 'skinbase:flag-legacy-users
                            {--dry-run : Show what would be updated without writing to DB}
                            {--chunk=500 : Chunk size for processing}';

    protected $description = 'Set should_migrate=1 on legacy users that have any activity across 14 tables (artworks_comments, artworks_downloads, blog_articles, chat, favourites, featured_works, forum_posts, forum_topics, friends_list, news, news_comment, users_comments, users_opinions, wallz)';

    /**
     * Activity tables to check — all confirmed to have a `user_id` column.
     */
    private const ACTIVITY_TABLES = [
        'artworks_comments',
        'artworks_downloads',
        'blog_articles',
        'chat',
        'favourites',
        'featured_works',
        'forum_posts',
        'forum_topics',
        'friends_list',
        'news',
        'news_comment',
        'users_comments',
        'users_opinions',
        'wallz',
    ];

    public function handle(): int
    {
        try {
            DB::connection('legacy')->getPdo();
        } catch (\Throwable) {
            $this->error('Legacy DB connection is not available.');
            return self::FAILURE;
        }

        $chunkSize = (int) $this->option('chunk');
        $dryRun    = (bool) $this->option('dry-run');

        if ($dryRun) {
            $this->warn('[DRY RUN] No changes will be written to the database.');
        }

        $this->info('Scanning legacy users for activity…');
        $this->newLine();

        $totalFlagged = 0;
        $totalSkipped = 0;
        $processed    = 0;

        DB::connection('legacy')
            ->table('users')
            ->orderBy('user_id')
            ->chunk($chunkSize, function ($users) use ($dryRun, &$totalFlagged, &$totalSkipped, &$processed) {
                $ids = $users->pluck('user_id')->map(fn ($v) => (int) $v)->all();

                // Collect all user_ids that have at least one row in any activity table.
                $activeIds = collect();

                foreach (self::ACTIVITY_TABLES as $table) {
                    $found = DB::connection('legacy')
                        ->table($table)
                        ->whereIn('user_id', $ids)
                        ->distinct()
                        ->pluck('user_id')
                        ->map(fn ($v) => (int) $v);

                    $activeIds = $activeIds->merge($found);
                }

                $activeIds = $activeIds->unique()->values();

                // Report per-user
                foreach ($users as $u) {
                    $id       = (int) $u->user_id;
                    $isActive = $activeIds->contains($id);

                    if ($isActive) {
                        $this->line(sprintf(
                            '  <fg=green>ACTIVE</>  id=%-8d  uname=<fg=yellow>%s</>',
                            $id,
                            $u->uname ?? '(no username)',
                        ));
                        $totalFlagged++;
                    } else {
                        $totalSkipped++;
                    }
                }

                // Bulk update in one query
                if (! $dryRun && $activeIds->isNotEmpty()) {
                    DB::connection('legacy')
                        ->table('users')
                        ->whereIn('user_id', $activeIds->all())
                        ->update(['should_migrate' => 1]);
                }

                $processed += count($ids);
                $this->line(sprintf(
                    '  … processed <fg=cyan>%d</> users so far (flagged: <fg=green>%d</>, skipped: %d)',
                    $processed, $totalFlagged, $totalSkipped,
                ));
            });

        $this->newLine();
        $this->info(sprintf(
            'Done.  %d user(s) flagged as should_migrate=1  /  %d user(s) left at 0.',
            $totalFlagged,
            $totalSkipped,
        ));

        if ($dryRun) {
            $this->warn('[DRY RUN] Nothing was written to the database.');
        }

        return self::SUCCESS;
    }
}
