<?php

namespace App\Console\Commands;

use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Mtc\MercuryDataModels\ModelHasRole;
use Mtc\MercuryDataModels\User;

class ExpireInvitedUsers extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'users:expire-invitations
        {--days=30 : Days an invite may stay unactivated before the account is removed}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Delete invited users who never activated their account within the configured window';

    /**
     * Execute the console command.
     */
    public function handle(): int
    {
        $days = (int) $this->option('days');
        $cutoff = Carbon::now()->subDays($days);

        $expired = 0;
        $this->expiredInviteQuery($cutoff)
            ->each(function (User $user) use (&$expired) {
                $this->expireUser($user);
                $expired++;
            });

        $this->info("Expired {$expired} invited user(s) not activated within {$days} days.");

        return self::SUCCESS;
    }

    /**
     * Users who never logged in and whose most recent dated invite predates the cutoff.
     *
     * Invites with a NULL created_at carry no reliable date (they predate invite
     * timestamping) and are ignored entirely, so they never trigger a deletion.
     */
    private function expiredInviteQuery(Carbon $cutoff): Builder
    {
        return User::query()
            ->whereNull('last_login_at')
            ->whereHas('tenants', fn (Builder $query) => $query->whereNotNull('tenant_users.created_at'))
            ->whereDoesntHave('tenants', fn (Builder $query) => $query
                ->whereNotNull('tenant_users.created_at')
                ->where('tenant_users.created_at', '>=', $cutoff));
    }

    /**
     * Remove the user along with their site links and role assignments.
     */
    private function expireUser(User $user): void
    {
        DB::connection($user->getConnectionName())->transaction(function () use ($user) {
            $user->tenants()->detach();
            ModelHasRole::query()
                ->where('model_type', 'user')
                ->where('model_id', $user->id)
                ->delete();
            $user->delete();
        });
    }
}
