<?php

declare(strict_types=1);

use App\Models\Project;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Queue;

uses(DatabaseTransactions::class);

beforeEach(function () {
    Queue::fake();

    $this->tenant = Tenant::factory()->withRequisites()->create();
    $this->user = User::factory()->create(['tenant_id' => $this->tenant->id]);

    DB::statement('SET app.current_tenant_id = '.$this->tenant->id);
});

it('logs project.created when a project is stored', function () {
    $this->actingAs($this->user)->postJson('/api/projects', [
        'name' => 'Окна СПб',
        'signal_type' => 'site',
        'signal_identifier' => 'okna-spb.ru',
        'daily_limit_target' => 50,
        'regions' => [],
        'delivery_days_mask' => 127,
    ])->assertStatus(201);

    $row = DB::table('tenant_operations_log')
        ->where('tenant_id', $this->tenant->id)
        ->where('event', 'project.created')
        ->first();

    expect($row)->not->toBeNull();
    expect($row->entity_type)->toBe('project');
});

it('logs project.updated with before/after diff when a project is patched', function () {
    $project = Project::factory()->create([
        'tenant_id' => $this->tenant->id,
        'daily_limit_target' => 10,
    ]);

    $this->actingAs($this->user)->patchJson("/api/projects/{$project->id}", [
        'daily_limit_target' => 20,
    ])->assertOk();

    $row = DB::table('tenant_operations_log')
        ->where('tenant_id', $this->tenant->id)
        ->where('event', 'project.updated')
        ->where('entity_id', $project->id)
        ->first();

    expect($row)->not->toBeNull();

    $before = json_decode($row->payload_before, true);
    $after = json_decode($row->payload_after, true);

    expect($before)->toHaveKey('daily_limit_target');
    expect($after)->toHaveKey('daily_limit_target');
    expect((int) $after['daily_limit_target'])->toBe(20);
});

it('logs project.deleted when a project is destroyed', function () {
    $project = Project::factory()->create(['tenant_id' => $this->tenant->id]);

    $this->actingAs($this->user)->deleteJson("/api/projects/{$project->id}")
        ->assertNoContent();

    $row = DB::table('tenant_operations_log')
        ->where('tenant_id', $this->tenant->id)
        ->where('event', 'project.deleted')
        ->where('entity_id', $project->id)
        ->first();

    expect($row)->not->toBeNull();
    expect($row->entity_type)->toBe('project');
});

it('logs project.bulk_<action> when a bulk action is executed', function () {
    $p1 = Project::factory()->create(['tenant_id' => $this->tenant->id, 'is_active' => true]);
    $p2 = Project::factory()->create(['tenant_id' => $this->tenant->id, 'is_active' => true]);

    $this->actingAs($this->user)->postJson('/api/projects/bulk', [
        'action' => 'pause',
        'ids' => [$p1->id, $p2->id],
    ])->assertOk()->assertJsonPath('updated', 2);

    $row = DB::table('tenant_operations_log')
        ->where('tenant_id', $this->tenant->id)
        ->where('event', 'like', 'project.bulk_%')
        ->first();

    expect($row)->not->toBeNull();
    expect($row->entity_type)->toBe('project');
});
