<?php

declare(strict_types=1);

namespace Tests\Feature\Filament;

use App\Filament\Pages\CompanySettings;
use App\Models\Company;
use App\Models\Plan;
use App\Models\Subscription;
use App\Models\SubscriptionRequest;
use App\Models\User;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Livewire\Livewire;
use PHPUnit\Framework\Attributes\Test;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

/**
 * #171 — la empresa tiene autogestión de suscripción: la página `CompanySettings`
 * (pestaña "Suscripción") muestra plan/uso y su acción "Solicitar Cambio" crea
 * solicitudes TIPADAS (upgrade/downgrade/más usuarios/etc.), no solo un
 * `upgrade_plan` hardcodeado. El evento `created` notifica a los super_admins.
 *
 * (El flujo hardcodeado a `upgrade_plan` es el de `/suscripcion`, que es la
 * REACTIVACIÓN post-expiración — de un solo propósito por diseño.)
 */
class SelfServeSubscriptionRequestTest extends TestCase
{
    use DatabaseTransactions;

    private function companyAdmin(): User
    {
        // `super_admin` debe existir: crear la solicitud dispara el evento `created`
        // → `notifySuperAdmins()` → `User::role('super_admin')`, que lanza
        // RoleDoesNotExist si el rol no existe (falla en la BD fresca de CI).
        Role::firstOrCreate(['name' => 'super_admin', 'guard_name' => 'web']);
        Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']);
        $company = Company::factory()->create();
        $plan = Plan::factory()->create(['is_active' => true]);
        Subscription::factory()->active()->create([
            'company_id' => $company->id,
            'plan_id' => $plan->id,
            'ends_at' => now()->addYear(),
        ]);
        $admin = User::factory()->create(['company_id' => $company->id]);
        $admin->assignRole('admin');

        $this->actingAs($admin);
        Filament::setCurrentPanel(Filament::getDefaultPanel());

        return $admin;
    }

    #[Test]
    public function a_company_admin_can_submit_a_typed_limit_increase_request(): void
    {
        $admin = $this->companyAdmin();

        Livewire::test(CompanySettings::class)
            ->callAction('request_change', [
                'request_type' => SubscriptionRequest::TYPE_INCREASE_USERS,
                'requested_value' => '20',
                'comments' => 'Necesitamos más usuarios para la temporada.',
            ]);

        $this->assertDatabaseHas('subscription_requests', [
            'company_id' => $admin->company_id,
            'request_type' => SubscriptionRequest::TYPE_INCREASE_USERS,
            'requested_value' => '20',
            'status' => SubscriptionRequest::STATUS_PENDING,
        ]);
    }

    #[Test]
    public function a_company_admin_can_request_a_plan_upgrade_to_a_specific_plan(): void
    {
        $admin = $this->companyAdmin();
        $target = Plan::factory()->create(['is_active' => true, 'name' => 'Enterprise Plus']);

        Livewire::test(CompanySettings::class)
            ->callAction('request_change', [
                'request_type' => SubscriptionRequest::TYPE_UPGRADE_PLAN,
                'requested_plan_id' => $target->id,
                'comments' => 'Queremos subir de plan.',
            ]);

        $this->assertDatabaseHas('subscription_requests', [
            'company_id' => $admin->company_id,
            'request_type' => SubscriptionRequest::TYPE_UPGRADE_PLAN,
            'requested_plan_id' => $target->id,
            'status' => SubscriptionRequest::STATUS_PENDING,
        ]);
    }
}
