<?php

namespace Tests\Feature\Api;

use App\Models\User;
use App\Modules\Tenant\Models\Company;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class FeatureAccessApiTest extends TestCase
{
    use RefreshDatabase;

    public function test_enabled_feature_allows_module_access(): void
    {
        [$user, $company] = $this->createCompanyMember();
        $this->attachActiveSubscription($company, ['invoice']);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->getJson('/api/v1/customers')
            ->assertOk();
    }

    public function test_missing_feature_blocks_module_access(): void
    {
        [$user, $company] = $this->createCompanyMember();
        $this->attachActiveSubscription($company, ['invoice']);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->getJson('/api/v1/pos/sales')
            ->assertForbidden()
            ->assertJsonPath('message', 'This module is not enabled on the current plan');
    }

    public function test_company_without_active_subscription_cannot_access_feature_modules(): void
    {
        [$user, $company] = $this->createCompanyMember();

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->getJson('/api/v1/customers')
            ->assertForbidden()
            ->assertJsonPath('message', 'This module requires an active subscription');
    }

    public function test_current_company_response_includes_enabled_features(): void
    {
        [$user, $company] = $this->createCompanyMember();
        $this->attachActiveSubscription($company, ['invoice', 'pos']);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->getJson('/api/v1/tenant/current')
            ->assertOk()
            ->assertJsonPath('data.company.subscription.plan.features.0.slug', 'invoice')
            ->assertJsonPath('data.company.subscription.plan.features.1.slug', 'pos');
    }

    public function test_current_company_response_includes_role_permissions(): void
    {
        [$user, $company] = $this->createCompanyMember(role: 'member');
        $this->attachActiveSubscription($company, ['invoice']);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->getJson('/api/v1/tenant/current')
            ->assertOk()
            ->assertJsonPath('data.company.user_role', 'member')
            ->assertJsonPath('data.company.permissions.0', 'invoice.view');
    }

    public function test_member_can_view_enabled_module_but_cannot_manage_it(): void
    {
        [$user, $company] = $this->createCompanyMember(role: 'member');
        $this->attachActiveSubscription($company, ['invoice']);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->getJson('/api/v1/customers')
            ->assertOk();

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->postJson('/api/v1/customers', [
                'name' => 'Read Only Customer',
            ])
            ->assertForbidden()
            ->assertJsonPath('message', 'Permission denied');
    }

    public function test_admin_can_manage_enabled_module(): void
    {
        [$user, $company] = $this->createCompanyMember(role: 'admin');
        $this->attachActiveSubscription($company, ['invoice']);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->postJson('/api/v1/customers', [
                'name' => 'Admin Customer',
            ])
            ->assertCreated()
            ->assertJsonPath('data.name', 'Admin Customer');
    }

    /**
     * @return array{0: User, 1: Company}
     */
    private function createCompanyMember(string $role = 'owner'): array
    {
        $user = User::factory()->create();
        $company = Company::query()->create([
            'name' => 'ABC Grocery',
            'slug' => 'abc-grocery',
            'status' => 'active',
        ]);

        $company->users()->attach($user->id, [
            'role' => $role,
            'joined_at' => now(),
        ]);

        return [$user, $company];
    }
}
