<?php

namespace Tests\Feature;

use App\Models\Company;
use App\Models\Document;
use App\Models\Permission;
use App\Models\Role;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Tests\TestCase;

class DocumentsModuleTest extends TestCase
{
    use RefreshDatabase;

    public function test_documents_links_are_accessible_for_authorized_user(): void
    {
        $user = $this->createUserWithDocumentPermissions();

        $this->actingAs($user)->get(route('documents.dashboard'))->assertOk();
        $this->actingAs($user)->get(route('documents.index'))->assertOk();
        $this->actingAs($user)->get(route('documents.create'))->assertOk();
    }

    public function test_document_store_validates_required_fields(): void
    {
        Storage::fake('local');
        $user = $this->createUserWithDocumentPermissions();

        $response = $this->actingAs($user)->post(route('documents.store'), [
            'name' => '',
            'category' => '',
        ]);

        $response->assertSessionHasErrors(['name', 'category', 'document']);
    }

    public function test_document_upload_and_filter_work(): void
    {
        Storage::fake('local');
        $user = $this->createUserWithDocumentPermissions();

        $this->actingAs($user)->post(route('documents.store'), [
            'name' => 'HR Policy 2026',
            'category' => 'other',
            'visibility' => 'company',
            'document' => UploadedFile::fake()->create('policy.pdf', 200, 'application/pdf'),
        ])->assertRedirect(route('documents.index'));

        $this->actingAs($user)
            ->get(route('documents.index', ['search' => 'Policy']))
            ->assertOk()
            ->assertSee('HR Policy 2026');
    }

    public function test_document_visibility_is_company_scoped(): void
    {
        $owner = $this->createUserWithDocumentPermissions('owner@demo.local');
        $otherCompanyUser = $this->createUserWithDocumentPermissions('other@demo.local', false);

        $doc = Document::query()->create([
            'company_id' => $owner->company_id,
            'name' => 'Company Secret Doc',
            'type' => 'other',
            'category' => 'other',
            'path' => 'documents/company-secret.pdf',
            'uploaded_by' => $owner->id,
            'visibility' => 'company',
            'status' => 'active',
        ]);

        $this->actingAs($otherCompanyUser)->get(route('documents.download', $doc))->assertNotFound();
    }

    private function createUserWithDocumentPermissions(string $email = 'doc-admin@demo.local', bool $sameCompany = true): User
    {
        if ($email === 'doc-admin@demo.local') {
            $email = 'doc-admin+' . Str::uuid() . '@demo.local';
        }

        $company = Company::query()->create([
            'name' => $sameCompany ? 'Demo Company' : 'Other Company',
            'short_name' => $sameCompany ? 'DEMO' : 'OTHR',
            'email' => $email,
            'status' => 'active',
        ]);

        $permissions = collect(['documents_view', 'documents_create', 'documents_edit'])
            ->map(fn (string $name) => Permission::query()->firstOrCreate(['name' => $name], ['display_name' => $name]));

        $role = Role::withoutGlobalScopes()->create([
            'company_id' => $company->id,
            'name' => 'admin',
            'display_name' => 'Admin',
        ]);
        $role->permissions()->sync($permissions->pluck('id')->all());

        return User::factory()->create([
            'email' => $email,
            'company_id' => $company->id,
            'role_id' => $role->id,
            'user_type' => \App\Models\User::USER_TYPE_ADMIN,
            'is_superadmin' => false,
            'allow_login' => true,
            'status' => 'active',
        ]);
    }
}
