<?php

namespace App\Console\Commands;

use App\Mail\AutoTraderLocationAccessFailedMail;
use App\Models\AutoTraderLocationStatus;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Mail;

/**
 * Alerts about AutoTrader locations we can no longer fetch stock for because we
 * have lost (or never had) access. Failures are recorded during the stock sync;
 * this command reports them on a Fibonacci cadence so a persistent issue is not
 * re-sent every day. Live sites alert the website admins, dev sites the MTC team
 * (AUTO-957).
 */
class CheckAutoTraderLocationAccess extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'check:auto-trader-location-access';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Alert about AutoTrader locations we have lost access to when fetching stock';

    /**
     * Execute the console command.
     */
    public function handle(): int
    {
        if ($this->shouldSkipTask()) {
            return self::SUCCESS;
        }

        tenancy()->runForMultiple(null, function ($tenant) {
            $dueLocations = AutoTraderLocationStatus::query()
                ->forTenant($tenant->id)
                ->failing()
                ->get()
                ->filter(fn (AutoTraderLocationStatus $status) => $status->isDueForAlert());

            if ($dueLocations->isEmpty()) {
                return;
            }

            $this->alertTenant($tenant, $dueLocations);
        });

        return self::SUCCESS;
    }

    /**
     * Send the access-failure alert for a tenant and record that it was sent.
     */
    private function alertTenant($tenant, Collection $dueLocations): void
    {
        $recipients = array_filter((array) config('mail.developer_alerts'));

        if (empty($recipients)) {
            $this->warn("No developer alert emails configured; AutoTrader access alert skipped");
            return;
        }

        try {
            Mail::to($recipients)
                ->send(new AutoTraderLocationAccessFailedMail($dueLocations, !empty($tenant->live_at)));

            $dueLocations->each(fn (AutoTraderLocationStatus $status) => $status->markAlerted());

            $this->info("AutoTrader access alert sent for tenant {$tenant->id} ({$dueLocations->count()} location(s))");
        } catch (\Exception $e) {
            $this->error("Failed to send AutoTrader access alert for tenant {$tenant->id}: {$e->getMessage()}");
        }
    }

    /**
     * Determine if the task should be skipped based on the environment.
     */
    private function shouldSkipTask(): bool
    {
        return in_array(app()->environment(), ['local', 'production'], true) === false
            && app()->runningUnitTests() === false;
    }
}
