<?php

use App\Enums\IsShow;
use App\Livewire\Datatable\Information\TestimonialsTable;
use App\Livewire\Studio\Information\Testimonial;
use App\Models\Customer;
use App\Models\Testimonial as TestimonialModel;
use App\Models\User;
use Livewire\Livewire;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

beforeEach(function () {
    $this->setupUser();

    $role = Role::firstOrCreate(['name' => 'Owner']);
    Permission::firstOrCreate(['name' => 'view testimonial']);
    $role->givePermissionTo(['view testimonial']);
    $this->user->assignRole($role);
});

it('renders the testimonial page correctly', function () {
    $this->actingAs($this->user)
        ->get(route('studio.information.testimonial.index'))
        ->assertOk()
        ->assertSeeLivewire(Testimonial::class);
});

it('displays testimonials in datatable', function () {
    $user = User::factory()->create();
    $customer = Customer::factory()->create(['user_id' => $user->id]);

    $testimonial = TestimonialModel::factory()->create([
        'user_id' => $user->id,
        'content' => 'Produk sangat bagus dan berkualitas',
        'rating' => 5,
        'is_show' => IsShow::SHOW,
    ]);

    Livewire::actingAs($this->user)
        ->test(TestimonialsTable::class)
        ->assertSee($customer->name)
        ->assertSee('Produk sangat bagus dan berkualitas')
        ->assertSee('5');
});

it('can toggle testimonial visibility to hidden', function () {
    $user = User::factory()->create();
    $customer = Customer::factory()->create(['user_id' => $user->id]);

    $testimonial = TestimonialModel::factory()->create([
        'user_id' => $user->id,
        'is_show' => IsShow::SHOW,
    ]);

    Livewire::actingAs($this->user)
        ->test(TestimonialsTable::class)
        ->call('toggleShow', $testimonial)
        ->assertOk();

    $testimonial->refresh();
    expect($testimonial->is_show)->toBe(IsShow::HIDDEN);

    $this->assertDatabaseHas('testimonials', [
        'id' => $testimonial->id,
        'is_show' => IsShow::HIDDEN->value,
    ]);
});

it('can toggle testimonial visibility to show', function () {
    $user = User::factory()->create();
    $customer = Customer::factory()->create(['user_id' => $user->id]);

    $testimonial = TestimonialModel::factory()->hidden()->create([
        'user_id' => $user->id,
    ]);

    Livewire::actingAs($this->user)
        ->test(TestimonialsTable::class)
        ->call('toggleShow', $testimonial)
        ->assertOk();

    $testimonial->refresh();
    expect($testimonial->is_show)->toBe(IsShow::SHOW);

    $this->assertDatabaseHas('testimonials', [
        'id' => $testimonial->id,
        'is_show' => IsShow::SHOW->value,
    ]);
});

it('filters testimonials by show scope', function () {
    $user1 = User::factory()->create();
    $user2 = User::factory()->create();
    $customer1 = Customer::factory()->create(['user_id' => $user1->id]);
    $customer2 = Customer::factory()->create(['user_id' => $user2->id]);

    $shownTestimonial = TestimonialModel::factory()->show()->create([
        'user_id' => $user1->id,
        'content' => 'Testimonial yang ditampilkan',
    ]);

    $hiddenTestimonial = TestimonialModel::factory()->hidden()->create([
        'user_id' => $user2->id,
        'content' => 'Testimonial yang disembunyikan',
    ]);

    $shownTestimonials = TestimonialModel::query()->show()->get();

    expect($shownTestimonials->pluck('id'))->toContain($shownTestimonial->id);
    expect($shownTestimonials->pluck('id'))->not->toContain($hiddenTestimonial->id);
});

it('displays testimonial with correct rating', function () {
    $user = User::factory()->create();
    $customer = Customer::factory()->create(['user_id' => $user->id]);

    $testimonial = TestimonialModel::factory()->create([
        'user_id' => $user->id,
        'rating' => 4,
    ]);

    Livewire::actingAs($this->user)
        ->test(TestimonialsTable::class)
        ->assertSee('4');

    expect($testimonial->rating)->toBe(4);
});

it('truncates long testimonial content in datatable', function () {
    $user = User::factory()->create();
    $customer = Customer::factory()->create(['user_id' => $user->id]);
    $longContent = str_repeat('Ini adalah testimonial yang sangat panjang. ', 10);

    $testimonial = TestimonialModel::factory()->create([
        'user_id' => $user->id,
        'content' => $longContent,
    ]);

    Livewire::actingAs($this->user)
        ->test(TestimonialsTable::class)
        ->assertSee('...');
});

it('shows testimonial with user relationship', function () {
    $user = User::factory()->create();
    $customer = Customer::factory()->create(['user_id' => $user->id, 'name' => 'John Doe']);

    $testimonial = TestimonialModel::factory()->create([
        'user_id' => $user->id,
    ]);

    $testimonial->load('user.customer');

    expect($testimonial->user)->not->toBeNull();
    expect($testimonial->user->customer->name)->toBe('John Doe');
});

it('can search testimonials by customer name', function () {
    $user1 = User::factory()->create();
    $user2 = User::factory()->create();
    $customer1 = Customer::factory()->create(['user_id' => $user1->id, 'name' => 'Alice Johnson']);
    $customer2 = Customer::factory()->create(['user_id' => $user2->id, 'name' => 'Bob Smith']);

    TestimonialModel::factory()->create([
        'user_id' => $user1->id,
        'content' => 'Great product!',
    ]);

    TestimonialModel::factory()->create([
        'user_id' => $user2->id,
        'content' => 'Excellent service!',
    ]);

    Livewire::actingAs($this->user)
        ->test(TestimonialsTable::class)
        ->set('search', 'Alice')
        ->assertSee('Alice Johnson')
        ->assertDontSee('Bob Smith');
});

it('can search testimonials by content', function () {
    $user1 = User::factory()->create();
    $user2 = User::factory()->create();
    $customer1 = Customer::factory()->create(['user_id' => $user1->id]);
    $customer2 = Customer::factory()->create(['user_id' => $user2->id]);

    TestimonialModel::factory()->create([
        'user_id' => $user1->id,
        'content' => 'Produk sangat memuaskan',
    ]);

    TestimonialModel::factory()->create([
        'user_id' => $user2->id,
        'content' => 'Pelayanan ramah',
    ]);

    Livewire::actingAs($this->user)
        ->test(TestimonialsTable::class)
        ->set('search', 'memuaskan')
        ->assertSee('Produk sangat memuaskan')
        ->assertDontSee('Pelayanan ramah');
});

it('cannot access testimonial page without permission', function () {
    $this->user->roles()->detach();
    $this->user->permissions()->detach();

    $this->actingAs($this->user)
        ->get(route('studio.information.testimonial.index'))
        ->assertForbidden();
});
