<?php

use App\Models\Label;
use App\Models\Macro;
use App\Models\MacroAssignment;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('store requires authentication', function () {
    $response = $this->post(route('settings.macro-assignments.store'), []);
    $response->assertRedirect(route('login'));
});

test('store creates macro assignment', function () {
    $user = User::factory()->create();
    $macro = Macro::factory()->create();

    $response = $this->actingAs($user)
        ->postJson(route('settings.macro-assignments.store'), [
            'part_type' => 'song',
            'macro_id' => $macro->id,
            'position' => 'all_slides',
            'order' => 0,
        ]);

    $response->assertStatus(200)->assertJson(['success' => true]);
    expect(MacroAssignment::count())->toBe(1);
    expect(MacroAssignment::first()->part_type)->toBe('song');
});

test('store with by_label position and label_id', function () {
    $user = User::factory()->create();
    $macro = Macro::factory()->create();
    $label = Label::factory()->create();

    $response = $this->actingAs($user)
        ->postJson(route('settings.macro-assignments.store'), [
            'part_type' => 'sermon',
            'macro_id' => $macro->id,
            'position' => 'by_label',
            'label_id' => $label->id,
            'order' => 1,
        ]);

    $response->assertStatus(200);
    $assignment = MacroAssignment::first();
    expect($assignment->label_id)->toBe($label->id);
    expect($assignment->position)->toBe('by_label');
});

test('update modifies existing assignment', function () {
    $user = User::factory()->create();
    $macro = Macro::factory()->create();
    $assignment = MacroAssignment::create([
        'part_type' => 'song',
        'macro_id' => $macro->id,
        'position' => 'all_slides',
        'order' => 0,
    ]);

    $response = $this->actingAs($user)
        ->patchJson(route('settings.macro-assignments.update', $assignment), [
            'position' => 'first_slide',
            'order' => 5,
        ]);

    $response->assertStatus(200)->assertJson(['success' => true]);
    expect($assignment->fresh()->position)->toBe('first_slide');
    expect($assignment->fresh()->order)->toBe(5);
});

test('destroy deletes macro assignment', function () {
    $user = User::factory()->create();
    $macro = Macro::factory()->create();
    $assignment = MacroAssignment::create([
        'part_type' => 'song',
        'macro_id' => $macro->id,
        'position' => 'all_slides',
        'order' => 0,
    ]);

    $response = $this->actingAs($user)
        ->deleteJson(route('settings.macro-assignments.destroy', $assignment));

    $response->assertStatus(200)->assertJson(['success' => true]);
    expect(MacroAssignment::count())->toBe(0);
});

test('reorder updates order on multiple assignments', function () {
    $user = User::factory()->create();
    $macro = Macro::factory()->create();
    $a1 = MacroAssignment::create(['part_type' => 'song', 'macro_id' => $macro->id, 'position' => 'all_slides', 'order' => 0]);
    $a2 = MacroAssignment::create(['part_type' => 'song', 'macro_id' => $macro->id, 'position' => 'all_slides', 'order' => 1]);

    $response = $this->actingAs($user)
        ->postJson(route('settings.macro-assignments.reorder'), [
            'assignments' => [
                ['id' => $a1->id, 'order' => 5],
                ['id' => $a2->id, 'order' => 3],
            ],
        ]);

    $response->assertStatus(200);
    expect($a1->fresh()->order)->toBe(5);
    expect($a2->fresh()->order)->toBe(3);
});
