<?php

use App\Models\Action;
use App\Models\Activity;
use App\Models\Client;
use App\Models\ClientCase;
use App\Models\Decision;
use App\Models\Permission;
use App\Models\Person\Person;
use App\Models\Person\PersonGroup;
use App\Models\Person\PersonType;
use App\Models\Role;
use App\Models\Segment;
use App\Models\User;

function makeUserWithPermissions(array $perms = ['reports-view', 'reports-export']): \App\Models\User
{
    $user = User::factory()->create();
    $role = Role::create(['name' => 'Tester', 'slug' => 'tester']);
    foreach ($perms as $slug) {
        $p = Permission::firstOrCreate(['slug' => $slug], ['name' => strtoupper(str_replace('-', ' ', $slug))]);
        $role->permissions()->syncWithoutDetaching($p->id);
    }
    $role->users()->syncWithoutDetaching($user->id);

    return $user;
}

it('shows reports index with permission', function () {
    $user = makeUserWithPermissions(['reports-view']);
    $this->actingAs($user);

    $resp = $this->get(route('reports.index'));
    $resp->assertOk();
});

it('counts actions/decisions correctly', function () {
    $user = makeUserWithPermissions(['reports-view']);
    $this->actingAs($user);

    $action = Action::factory()->create(['name' => 'Klic']);
    $decision = Decision::create(['name' => 'Uspešno']);
    $group = new PersonGroup;
    $group->name = 'grp';
    $group->save();
    $type = PersonType::create(['name' => 'tip']);
    $person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
    $client = Client::create(['person_id' => $person->id]);
    $case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);

    Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
    Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
    Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);

    $resp = $this->getJson(route('reports.data', 'actions-decisions-counts'));
    $resp->assertOk();
    $json = $resp->json();
    expect($json['data'][0]['action_name'])->toBe('Klic');
    expect($json['data'][0]['decision_name'])->toBe('Uspešno');
    expect($json['data'][0]['activities_count'])->toBe(3);
});

it('lists active contracts filtered by client', function () {
    $user = makeUserWithPermissions(['reports-view']);
    $this->actingAs($user);

    // minimal person/client scaffolding
    $group = new PersonGroup; $group->name = 'grp'; $group->save();
    $type = PersonType::create(['name' => 'tip']);
    $p1 = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
    $p2 = Person::create(['first_name' => 'Bojan', 'last_name' => 'Drugi', 'full_name' => 'Bojan Drugi', 'group_id' => $group->id, 'type_id' => $type->id]);

    $clientA = App\Models\Client::create(['person_id' => $p1->id]);
    $clientB = App\Models\Client::create(['person_id' => $p2->id]);

    $caseA = ClientCase::create(['client_id' => $clientA->id, 'person_id' => $p1->id, 'client_ref' => 'A']);
    $caseB = ClientCase::create(['client_id' => $clientB->id, 'person_id' => $p2->id, 'client_ref' => 'B']);

    $ctype = new App\Models\ContractType;
    $ctype->name = 'Standard';
    $ctype->save();

    // Active contract for client A
    App\Models\Contract::create([
        'reference' => 'A-001',
        'client_case_id' => $caseA->id,
        'type_id' => $ctype->id,
        'start_date' => now()->subDays(10)->toDateString(),
        'end_date' => null,
    ]);

    // Inactive for client A (ended yesterday)
    App\Models\Contract::create([
        'reference' => 'A-OLD',
        'client_case_id' => $caseA->id,
        'type_id' => $ctype->id,
        'start_date' => now()->subMonths(2)->toDateString(),
        'end_date' => now()->subDay()->toDateString(),
    ]);

    // Active but for different client B (should be excluded by client filter)
    App\Models\Contract::create([
        'reference' => 'B-001',
        'client_case_id' => $caseB->id,
        'type_id' => $ctype->id,
        'start_date' => now()->subDays(3)->toDateString(),
        'end_date' => null,
    ]);

    $resp = $this->getJson(route('reports.data', ['slug' => 'active-contracts', 'client_uuid' => $clientA->uuid, 'as_of' => now()->toDateString()]));
    $resp->assertOk();
    $json = $resp->json();

    // Should list exactly the active one for client A
    expect($json['data'])->toBeArray();
    // Filter only references from result
    $refs = array_map(fn ($r) => $r['contract_reference'] ?? null, $json['data']);
    expect($refs)->toContain('A-001');
    expect($refs)->not->toContain('A-OLD');
    expect($refs)->not->toContain('B-001');
});

it('counts activities per segment', function () {
    $user = makeUserWithPermissions(['reports-view']);
    $this->actingAs($user);

    $segment = Segment::create(['name' => 'Prioriteta A', 'description' => 'desc', 'active' => true]);
    $action = Action::factory()->create(['segment_id' => $segment->id]);
    $decision = Decision::create(['name' => 'OK']);
    $group = new PersonGroup;
    $group->name = 'grp';
    $group->save();
    $type = PersonType::create(['name' => 'tip']);
    $person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
    $client = Client::create(['person_id' => $person->id]);
    $case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);

    Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
    Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);

    $resp = $this->getJson(route('reports.data', 'segment-activity-counts'));
    $resp->assertOk();
    $json = $resp->json();
    expect($json['data'][0]['segment_name'])->toBe('Prioriteta A');
    expect($json['data'][0]['activities_count'])->toBe(2);
});

it('groups activities per day', function () {
    $user = makeUserWithPermissions(['reports-view']);
    $this->actingAs($user);

    $action = Action::factory()->create();
    $decision = Decision::create(['name' => 'OK']);
    $group = new PersonGroup;
    $group->name = 'grp';
    $group->save();
    $type = PersonType::create(['name' => 'tip']);
    $person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
    $client = Client::create(['person_id' => $person->id]);
    $case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);
    // Create two today and one yesterday (explicit timestamps via insert to avoid auto-timestamp override)
    Activity::query()->insert([
        ['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id, 'created_at' => now(), 'updated_at' => now()],
        ['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id, 'created_at' => now(), 'updated_at' => now()],
        ['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id, 'created_at' => now()->subDay(), 'updated_at' => now()->subDay()],
    ]);

    $resp = $this->getJson(route('reports.data', ['slug' => 'activities-per-period', 'period' => 'day']));
    $resp->assertOk();
    $json = collect($resp->json('data'));
    // Find today row
    $todayRow = $json->first(function ($r) {
        return str_starts_with((string) $r['period'], date('Y-m-d'));
    });
    expect($todayRow)->not()->toBeNull();
    expect($todayRow['activities_count'])->toBe(2);
});

it('counts activities per decision only', function () {
    $user = makeUserWithPermissions(['reports-view']);
    $this->actingAs($user);

    $decision = Decision::create(['name' => 'OK']);
    $group = new PersonGroup;
    $group->name = 'grp';
    $group->save();
    $type = PersonType::create(['name' => 'tip']);
    $person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
    $client = Client::create(['person_id' => $person->id]);
    $case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);

    $action = Action::factory()->create();
    Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
    Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
    Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);

    $resp = $this->getJson(route('reports.data', 'decisions-counts'));
    $resp->assertOk();
    $json = $resp->json();
    expect($json['data'][0]['decision_name'])->toBe('OK');
    expect($json['data'][0]['activities_count'])->toBe(3);
});
