<?php

namespace Tests\Feature;

use App\Models\Central\Company;
use App\Models\Central\Plan;
use App\Models\Tenant\Client;
use App\Models\Tenant\ServiceReminderSent;
use App\Models\Tenant\TireSet;
use App\Models\Tenant\TireStorage;
use App\Tenancy\TenantManager;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Tests\TestCase;

class TireSeasonalReminderTest extends TestCase
{
    use RefreshDatabase;

    public function test_outside_window_does_nothing(): void
    {
        Carbon::setTestNow(Carbon::create(2026, 6, 2));
        $this->makeStoredSet('off', season: 'winter');

        \Illuminate\Support\Facades\Mail::fake();
        $this->artisan('tires:remind-seasonal')->assertSuccessful();

        $this->assertEquals(0, ServiceReminderSent::where('type', 'tire_swap')->count());
        Carbon::setTestNow();
    }

    public function test_spring_window_notifies_winter_stored_sets(): void
    {
        Carbon::setTestNow(Carbon::create(2026, 3, 1));
        $ctx = $this->makeStoredSet('spr', season: 'winter');

        \Illuminate\Support\Facades\Mail::fake();
        $this->artisan('tires:remind-seasonal')->assertSuccessful();

        $sent = ServiceReminderSent::where('type', 'tire_swap')
            ->where('client_id', $ctx['client']->id)->first();
        $this->assertNotNull($sent);
        Carbon::setTestNow();
    }

    public function test_spring_window_ignores_summer_sets(): void
    {
        Carbon::setTestNow(Carbon::create(2026, 3, 1));
        $this->makeStoredSet('sum', season: 'summer');

        \Illuminate\Support\Facades\Mail::fake();
        $this->artisan('tires:remind-seasonal')->assertSuccessful();

        $this->assertEquals(0, ServiceReminderSent::where('type', 'tire_swap')->count());
        Carbon::setTestNow();
    }

    public function test_autumn_window_notifies_summer_stored_sets(): void
    {
        Carbon::setTestNow(Carbon::create(2026, 10, 1));
        $ctx = $this->makeStoredSet('aut', season: 'summer');

        \Illuminate\Support\Facades\Mail::fake();
        $this->artisan('tires:remind-seasonal')->assertSuccessful();

        $sent = ServiceReminderSent::where('type', 'tire_swap')->first();
        $this->assertNotNull($sent);
        $this->assertEquals($ctx['client']->id, $sent->client_id);
        Carbon::setTestNow();
    }

    public function test_cooldown_prevents_double_send(): void
    {
        Carbon::setTestNow(Carbon::create(2026, 3, 1));
        $ctx = $this->makeStoredSet('cd', season: 'winter');

        \Illuminate\Support\Facades\Mail::fake();
        $this->artisan('tires:remind-seasonal')->assertSuccessful();
        $this->assertEquals(1, ServiceReminderSent::where('type', 'tire_swap')->count());

        // Second run same day → cooldown blocks it.
        $this->artisan('tires:remind-seasonal')->assertSuccessful();
        $this->assertEquals(1, ServiceReminderSent::where('type', 'tire_swap')->count());
        Carbon::setTestNow();
    }

    public function test_force_runs_outside_window(): void
    {
        Carbon::setTestNow(Carbon::create(2026, 6, 2));
        $ctx = $this->makeStoredSet('force', season: 'winter');

        \Illuminate\Support\Facades\Mail::fake();
        $this->artisan('tires:remind-seasonal', ['--force' => true])->assertSuccessful();

        $this->assertEquals(1, ServiceReminderSent::where('type', 'tire_swap')->count());
        Carbon::setTestNow();
    }

    private function makeStoredSet(string $slug, string $season): array
    {
        $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
        $company = Company::create([
            'plan_id' => $plan->id, 'slug' => $slug,
            'name' => ucfirst($slug), 'status' => 'active',
            'settings' => ['telegram' => ['bot_token' => 'FAKE:TOKEN']],
        ]);
        app(TenantManager::class)->setCurrent($company);

        $client = Client::create([
            'name' => 'TireClient', 'phone' => '+3736' . random_int(1000000, 9999999),
            'email' => $slug . '@example.com',
            'telegram_chat_id' => '9999' . random_int(1000, 9999),
            'type' => 'individual', 'status' => 'active',
        ]);

        $vehicle = \App\Models\Tenant\Vehicle::create([
            'client_id' => $client->id, 'make' => 'BMW', 'model' => 'X5',
            'plate' => 'TS-' . random_int(100, 999),
        ]);

        $set = TireSet::create([
            'client_id' => $client->id, 'vehicle_id' => $vehicle->id,
            'season' => $season, 'brand' => 'Michelin',
            'width' => 205, 'profile' => 55, 'diameter' => 16,
        ]);
        TireStorage::create([
            'tire_set_id' => $set->id, 'location' => 'A1-' . $slug,
            'status' => 'stored', 'checked_in_at' => now()->subMonths(2),
        ]);

        // Telegram dispatch goes through HTTP; fake it so the test doesn't
        // hit the real Bot API.
        \Illuminate\Support\Facades\Http::fake([
            'api.telegram.org/*' => \Illuminate\Support\Facades\Http::response(['ok' => true]),
        ]);

        return compact('company', 'client', 'vehicle', 'set');
    }
}
