<?php

use App\Models\Action;
use App\Models\ArchiveSetting;
use App\Models\Client;
use App\Models\ClientCase;
use App\Models\Contract;
use App\Models\ContractType;
use App\Models\Decision;
use App\Models\Segment;
use App\Models\User;
use Illuminate\Support\Facades\DB;

it('archives the contract when creating an activity with an archive event decision', function () {
    // Auth
    $user = User::factory()->create();
    $this->actingAs($user);

    // Minimal person/client/case
    $person = \App\Models\Person\Person::factory()->create([
        'first_name' => 'Test',
        'last_name' => 'User',
        'full_name' => 'Test User',
    ]);
    $client = Client::create(['person_id' => $person->id]);
    $case = ClientCase::create([
        'client_id' => $client->id,
        'person_id' => $person->id,
    ]);

    // Contract to be archived
    $ctype = ContractType::factory()->create();
    $contract = Contract::create([
        'client_case_id' => $case->id,
        'reference' => 'R-TEST',
        'start_date' => now()->toDateString(),
        'type_id' => $ctype->id,
        'description' => 'Test',
    ]);

    // ensure exists before triggering
    expect($contract->id)->toBeGreaterThan(0);

    // Action/Decision
    $segment = Segment::factory()->create();
    $action = Action::create(['name' => 'Call', 'color_tag' => '#000000', 'segment_id' => $segment->id]);
    $decision = Decision::create(['name' => 'Archive', 'color_tag' => '#ff0000', 'auto_mail' => false]);
    $action->decisions()->attach($decision->id);

    // Create initial and archive segments
    $initialSegment = Segment::factory()->create();
    $archiveSegment = Segment::factory()->create();

    // Ensure case and contract have an initial segment active
    DB::table('client_case_segment')->insert([
        'client_case_id' => $case->id,
        'segment_id' => $initialSegment->id,
        'active' => true,
        'created_at' => now(),
        'updated_at' => now(),
    ]);
    DB::table('contract_segment')->insert([
        'contract_id' => $contract->id,
        'segment_id' => $initialSegment->id,
        'active' => true,
        'created_at' => now(),
        'updated_at' => now(),
    ]);

    // Archive setting (focus on contracts table, soft archive) with archive segment
    $setting = ArchiveSetting::create([
        'name' => 'Test archive',
        'enabled' => true,
        'strategy' => 'immediate',
        'soft' => true,
        'reactivate' => false,
        'segment_id' => $archiveSegment->id,
        'entities' => [
            [
                'table' => 'contracts',
                'focus' => true,
            ],
        ],
    ]);

    // Event: archive_contract (ensure legacy NOT NULL options is satisfied)
    $eventId = DB::table('events')->insertGetId([
        'name' => 'Archive Contract',
        'key' => 'archive_contract',
        'description' => 'Archive selected contract',
        'active' => true,
        'options' => json_encode(new stdClass),
        'config' => json_encode(new stdClass),
        'created_at' => now(),
        'updated_at' => now(),
    ]);

    // Attach event to decision with required config
    DB::table('decision_event')->insert([
        'decision_id' => $decision->id,
        'event_id' => $eventId,
        'active' => true,
        'run_order' => 1,
        'config' => json_encode(['archive_setting_id' => $setting->id]),
        'created_at' => now(),
        'updated_at' => now(),
    ]);

    // POST activity (should synchronously trigger decision events in testing env)
    $route = route('clientCase.activity.store', $case);
    $this->post($route, [
        'action_id' => $action->id,
        'decision_id' => $decision->id,
        'contract_uuid' => $contract->uuid,
        'note' => 'Trigger archive',
    ])->assertSessionHasNoErrors();

    // Contract should now be archived (active = 0)
    $fresh = $contract->fresh();
    expect((int) $fresh->active)->toBe(0);

    // Segment should be moved to archive segment
    $activePivots = DB::table('contract_segment')->where('contract_id', $contract->id)->where('active', true)->get();
    expect($activePivots->count())->toBe(1);
    expect($activePivots->first()->segment_id)->toBe($archiveSegment->id);

    // Case should have archive segment attached and active
    $caseSeg = DB::table('client_case_segment')->where('client_case_id', $case->id)->where('segment_id', $archiveSegment->id)->first();
    expect($caseSeg)->not->toBeNull();
    expect((int) $caseSeg->active)->toBe(1);
});
