<?php

namespace Tests\Feature;

use App\Filament\Resources\TenantResource\Pages\ViewTenantLifecycle;
use App\Models\Tenant;
use App\Models\TenantLifecycleEvent;
use App\Models\User;
use Filament\Actions\Testing\TestAction;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\TestCase;

class TenantLifecycleManagementTest extends TestCase
{
    use RefreshDatabase;

    public function test_superadmin_can_update_limits(): void
    {
        $user = User::factory()->create(['role' => 'super_admin']);
        $tenant = Tenant::factory()->create([
            'max_photos_per_event' => 500,
            'max_storage_mb' => 1024,
        ]);

        $this->bootSuperAdminPanel($user);

        Livewire::test(ViewTenantLifecycle::class, ['record' => $tenant->id])
            ->callAction(TestAction::make('update_limits'), [
                'max_photos_per_event' => 750,
                'max_storage_mb' => 2048,
                'note' => 'adjusted for onboarding',
            ]);

        $tenant->refresh();

        $this->assertSame(750, $tenant->max_photos_per_event);
        $this->assertSame(2048, $tenant->max_storage_mb);
        $this->assertTrue(TenantLifecycleEvent::query()
            ->where('tenant_id', $tenant->id)
            ->where('type', 'limits_updated')
            ->exists());
    }

    public function test_superadmin_can_set_and_clear_grace_period(): void
    {
        $user = User::factory()->create(['role' => 'super_admin']);
        $tenant = Tenant::factory()->create();

        $this->bootSuperAdminPanel($user);

        $graceUntil = now()->addDays(14)->startOfDay();

        Livewire::test(ViewTenantLifecycle::class, ['record' => $tenant->id])
            ->callAction(TestAction::make('set_grace_period'), [
                'grace_period_ends_at' => $graceUntil->toDateTimeString(),
                'note' => 'billing exception',
            ]);

        $tenant->refresh();

        $this->assertSame(
            $graceUntil->toDateTimeString(),
            $tenant->grace_period_ends_at?->toDateTimeString()
        );
        $this->assertTrue(TenantLifecycleEvent::query()
            ->where('tenant_id', $tenant->id)
            ->where('type', 'grace_period_set')
            ->exists());

        Livewire::test(ViewTenantLifecycle::class, ['record' => $tenant->id])
            ->callAction(TestAction::make('clear_grace_period'));

        $tenant->refresh();

        $this->assertNull($tenant->grace_period_ends_at);
        $this->assertTrue(TenantLifecycleEvent::query()
            ->where('tenant_id', $tenant->id)
            ->where('type', 'grace_period_cleared')
            ->exists());
    }

    public function test_superadmin_can_update_subscription_expiry(): void
    {
        $user = User::factory()->create(['role' => 'super_admin']);
        $tenant = Tenant::factory()->create();

        $this->bootSuperAdminPanel($user);

        $expiresAt = now()->addMonths(3)->startOfDay();

        Livewire::test(ViewTenantLifecycle::class, ['record' => $tenant->id])
            ->callAction(TestAction::make('update_subscription_expires_at'), [
                'subscription_expires_at' => $expiresAt->toDateTimeString(),
                'note' => 'manual extension',
            ]);

        $tenant->refresh();

        $this->assertSame(
            $expiresAt->toDateTimeString(),
            $tenant->subscription_expires_at?->toDateTimeString()
        );
        $this->assertTrue(TenantLifecycleEvent::query()
            ->where('tenant_id', $tenant->id)
            ->where('type', 'subscription_expires_at_updated')
            ->exists());
    }

    private function bootSuperAdminPanel(User $user): void
    {
        $panel = Filament::getPanel('superadmin');

        $this->assertNotNull($panel);

        Filament::setCurrentPanel($panel);
        Filament::bootCurrentPanel();
        Filament::auth()->login($user);
    }
}
