<?php

namespace Tests\Feature;

use App\Mail\AutoTraderLocationAccessFailedMail;
use App\Models\AutoTraderLocationStatus;
use Carbon\Carbon;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Mail;
use Tests\DatabaseTestCase;

class CheckAutoTraderLocationAccessTest extends DatabaseTestCase
{
    private function createFailingLocation(int $failures = 1): AutoTraderLocationStatus
    {
        return AutoTraderLocationStatus::query()->create([
            'tenant_id' => tenant('id'),
            'advertiser_id' => '99999',
            'consecutive_failures' => $failures,
            'last_failure_at' => Carbon::now(),
            'last_error' => 'HTTP 403 - no access to advertiser 99999',
        ]);
    }

    public function testDevSiteAlertsDeveloperTeam(): void
    {
        Mail::fake();
        $location = $this->createFailingLocation();

        Artisan::call('check:auto-trader-location-access');

        Mail::assertSent(
            AutoTraderLocationAccessFailedMail::class,
            fn ($mail) => collect(config('mail.developer_alerts'))->contains(fn ($email) => $mail->hasTo($email))
        );

        $location->refresh();
        $this->assertSame(1, $location->alert_count);
        $this->assertNotNull($location->last_alerted_at);
    }

    public function testLiveSiteAlsoAlertsDeveloperTeam(): void
    {
        Mail::fake();

        tenant()->update(['live_at' => Carbon::now()]);
        $this->createFailingLocation();

        Artisan::call('check:auto-trader-location-access');

        Mail::assertSent(
            AutoTraderLocationAccessFailedMail::class,
            fn ($mail) => collect(config('mail.developer_alerts'))->contains(fn ($email) => $mail->hasTo($email))
        );
    }

    public function testFibonacciGateSuppressesThenResendsAlert(): void
    {
        Mail::fake();
        $this->createFailingLocation();

        Artisan::call('check:auto-trader-location-access');
        Mail::assertSentCount(1);

        // Gap (1 day) not yet elapsed -> suppressed.
        Carbon::setTestNow(Carbon::now()->addHours(6));
        Artisan::call('check:auto-trader-location-access');
        Mail::assertSentCount(1);

        // Gap elapsed -> alert again.
        Carbon::setTestNow(Carbon::now()->addDay());
        Artisan::call('check:auto-trader-location-access');
        Mail::assertSentCount(2);

        Carbon::setTestNow();
    }

    public function testRecoveredLocationIsNotAlerted(): void
    {
        Mail::fake();
        AutoTraderLocationStatus::recordCheck(tenant('id'), '99999', 200);

        Artisan::call('check:auto-trader-location-access');

        Mail::assertNothingSent();
    }
}
