<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Models\User;
use App\Services\Profile\CreatorEraService;
use App\Services\Profile\CreatorJourneyService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

/**
 * Rebuild creator eras independently of milestones.
 *
 * Usage:
 *   php artisan creator-journey:rebuild-eras              (all users)
 *   php artisan creator-journey:rebuild-eras {user_id}   (single user)
 */
class RebuildCreatorErasCommand extends Command
{
    protected $signature = 'creator-journey:rebuild-eras
                            {user_id? : Rebuild eras for a single user}
                            {--chunk=500 : Chunk size when rebuilding all}';

    protected $description = 'Rebuild creator era records from public artwork history (v2)';

    public function handle(CreatorEraService $eraService, CreatorJourneyService $journeys): int
    {
        $userId = $this->argument('user_id');

        if ($userId !== null) {
            return $this->rebuildSingle((int) $userId, $eraService, $journeys);
        }

        return $this->rebuildAll($eraService, $journeys, (int) $this->option('chunk'));
    }

    private function rebuildSingle(int $userId, CreatorEraService $eraService, CreatorJourneyService $journeys): int
    {
        $user = User::query()->find($userId);

        if (! $user) {
            $this->error("User {$userId} not found.");
            return self::FAILURE;
        }

        // Delegate to journeys service so eras + milestones stay in sync
        $journeys->rebuildForUser($user);

        $this->info("Rebuilt eras for user #{$userId}.");
        return self::SUCCESS;
    }

    private function rebuildAll(CreatorEraService $eraService, CreatorJourneyService $journeys, int $chunk): int
    {
        $total = DB::table('users')->whereNull('deleted_at')->count();
        $this->info("Rebuilding eras for {$total} users...");

        $bar = $this->output->createProgressBar($total);
        $bar->start();

        $eras = 0;

        DB::table('users')
            ->whereNull('deleted_at')
            ->orderBy('id')
            ->chunkById($chunk, function ($users) use ($journeys, $bar, &$eras): void {
                foreach ($users as $userRow) {
                    try {
                        $user = User::query()->find($userRow->id);
                        if ($user) {
                            $journeys->rebuildForUser($user);
                            $eras++;
                        }
                    } catch (\Throwable $e) {
                        $this->newLine();
                        $this->warn("Failed for user #{$userRow->id}: " . $e->getMessage());
                    }
                    $bar->advance();
                }
            });

        $bar->finish();
        $this->newLine();
        $this->info("Rebuilt eras for {$eras} users.");

        return self::SUCCESS;
    }
}
