<?php

namespace Tests\Feature;

use App\Domain\Subscription\ExpiryNotifier;
use App\Models\Plan;
use App\Models\Tenant;
use App\Models\User;
use App\Notifications\SubscriptionExpiringNotification;
use App\Support\Tenancy;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;

class ExpiryNotifierTest extends TestCase
{
    use RefreshDatabase;

    protected function tenantEndingIn(int $days): Tenant
    {
        $tenant = Tenant::create(['name' => 'C', 'slug' => 'c'.rand(1000, 9999), 'status' => 'active']);
        $tenant->subscription()->create([
            'plan_id' => Plan::first()->id, 'status' => 'active',
            'starts_at' => now()->subMonth(),
            'current_period_ends_at' => now()->addDays($days)->addHours(2),
        ]);

        app(Tenancy::class)->set($tenant);
        $owner = User::withoutEvents(fn () => User::create([
            'tenant_id' => $tenant->id, 'name' => 'O', 'email' => 'o'.rand(1000, 9999).'@x.com',
            'phone' => '07701234567', 'password' => 'password123',
        ]));
        $owner->assignRole('clinic_owner');
        app(Tenancy::class)->forget();

        return $tenant;
    }

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
        config(['whatsapp.driver' => 'log']);
    }

    public function test_d3_milestone_fires_in_app_and_email(): void
    {
        Notification::fake();
        $tenant = $this->tenantEndingIn(3);

        app(ExpiryNotifier::class)->run();

        Notification::assertSentTo(
            $tenant->users->first(),
            SubscriptionExpiringNotification::class,
        );
        $this->assertArrayHasKey('d3', $tenant->subscription->fresh()->expiry_notified);
    }

    public function test_each_milestone_fires_only_once(): void
    {
        Notification::fake();
        $tenant = $this->tenantEndingIn(1);

        $first = app(ExpiryNotifier::class)->run();
        $second = app(ExpiryNotifier::class)->run();

        $this->assertSame(1, $first);
        $this->assertSame(0, $second); // d1 already recorded
    }

    public function test_whatsapp_message_is_queued_for_owner(): void
    {
        $tenant = $this->tenantEndingIn(1);
        app(ExpiryNotifier::class)->run();

        $this->assertDatabaseHas('wa_messages', [
            'tenant_id' => $tenant->id,
            'to_phone' => '9647701234567',
        ]);
    }

    public function test_far_future_subscription_not_notified(): void
    {
        Notification::fake();
        $this->tenantEndingIn(20);

        $this->assertSame(0, app(ExpiryNotifier::class)->run());
        Notification::assertNothingSent();
    }
}
