<?php

declare(strict_types=1);

namespace Tests\Feature\Filament;

use App\Filament\Resources\SubscriptionRequests\SubscriptionRequestResource;
use App\Filament\Resources\Subscriptions\Pages\ListSubscriptions;
use App\Filament\Resources\Subscriptions\SubscriptionResource;
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;

/**
 * UX de los recursos de Administración. Antes el encabezado/breadcrump de una
 * suscripción mostraba el JSON crudo del Plan (recordTitleAttribute='plan', una
 * relación). Estos tests fijan títulos legibles y que el listado (con sus columnas
 * nuevas: plan.name, billing_cycle, status) renderiza sin reventar.
 */
class AdminResourcesUxTest extends TestCase
{
    use DatabaseTransactions;

    private function superAdmin(): User
    {
        Role::firstOrCreate(['name' => 'super_admin', 'guard_name' => 'web']);
        $super = User::factory()->create(['company_id' => null]);
        $super->assignRole('super_admin');
        $this->actingAs($super);
        Filament::setCurrentPanel(Filament::getDefaultPanel());

        return $super;
    }

    #[Test]
    public function subscription_record_title_is_human_readable_not_json(): void
    {
        $this->superAdmin();
        $company = Company::factory()->create(['name' => 'Acme S.A.']);
        $plan = Plan::factory()->create(['name' => 'Profesional']);
        $sub = Subscription::factory()->create([
            'company_id' => $company->id,
            'plan_id' => $plan->id,
        ]);

        $title = SubscriptionResource::getRecordTitle($sub->fresh());

        $this->assertIsString($title);
        $this->assertStringContainsString('Acme S.A.', $title);
        $this->assertStringContainsString('Profesional', $title);
        $this->assertStringNotContainsString('{', $title); // sin JSON
    }

    #[Test]
    public function subscription_request_record_title_is_human_readable(): void
    {
        $super = $this->superAdmin();
        $company = Company::factory()->create(['name' => 'Beta Ltda.']);
        $request = SubscriptionRequest::create([
            'company_id' => $company->id,
            'requested_by_user_id' => $super->id,
            'request_type' => SubscriptionRequest::TYPE_UPGRADE_PLAN,
            'comments' => 'x',
        ]);

        $title = SubscriptionRequestResource::getRecordTitle($request->fresh());

        $this->assertStringContainsString('Solicitud #'.$request->getKey(), $title);
        $this->assertStringContainsString('Beta Ltda.', $title);
    }

    #[Test]
    public function subscriptions_list_renders_with_the_reworked_columns(): void
    {
        $this->superAdmin();
        $company = Company::factory()->create();
        $plan = Plan::factory()->create();
        $sub = Subscription::factory()->create([
            'company_id' => $company->id,
            'plan_id' => $plan->id,
            'billing_cycle' => Subscription::BILLING_ANNUAL,
            'status' => Subscription::STATUS_ACTIVE,
        ]);

        Livewire::test(ListSubscriptions::class)
            ->assertOk()
            ->assertCanSeeTableRecords([$sub]);
    }
}
