<?php

namespace App\Console\Commands;

use App\Models\Seed;
use App\Traits\TrackedSeeding;
use Database\Seeders\Tenant\EnquiryTypeSeeder;
use Database\Seeders\Tenant\PageTypeDefaultTemplateSeed;
use Database\Seeders\ThemeContentSeeder;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\File;
use Mtc\Crm\Seeds\EnquiryStatusSeeder;
use Stancl\Tenancy\Concerns\HasATenantsOption;

class SeedTenantsCommand extends Command
{
    use TrackedSeeding;
    use HasATenantsOption;

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'tenants:seed {--retry}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Seed new data for tenants';

    private $batch = 0;

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        if ($this->option('retry')) {
            $this->retryLast();
        } else {
            $this->runSeed();
        }
        return Command::SUCCESS;
    }

    private function runSeed(): void
    {
        $seeds = $this->getSeeders();

        tenancy()->runForMultiple($this->option('tenants'), function ($tenant) use ($seeds) {
            $this->line("Tenant: {$tenant->getTenantKey()}");
            $this->batch = Seed::query()->max('batch') ?? 0;
            $this->batch++;
            $seeds->each(fn ($seeder) => $this->trackedSeed($seeder));
        });
    }

    private function retryLast()
    {
        tenancy()->runForMultiple(null, function ($tenant) {
            $this->line("Tenant: {$tenant->getTenantKey()}");
            $this->batch = Seed::query()->max('batch') ?? 0;

            Seed::query()
                ->where('batch', $this->batch)
                ->get()
                ->each(fn ($seeder) => $this->trackedSeed($seeder->seeder, true));
        });
    }

    private function getSeeders(): Collection
    {
        if (File::exists(base_path('vendor/composer/autoload_classmap.php')) === false) {
            throw new \Exception('No classmap to determine seeders');
        }

        $seeds = collect(require(base_path('vendor/composer/autoload_classmap.php')))
            ->filter(fn ($path, $class) => str_starts_with($class, 'Database\\Seeders\\Tenant\\'))
            ->keys()
            ->merge([
                EnquiryStatusSeeder::class,
                ThemeContentSeeder::class,
            ]);

        $priority = [
            EnquiryTypeSeeder::class,
            PageTypeDefaultTemplateSeed::class,
        ];

        return collect($priority)
            ->merge($seeds->reject(fn ($class) => in_array($class, $priority)));
    }
}
