<?php

namespace Tests\Feature;

use App\Models\ClientCase;
use App\Models\Contract;
use App\Models\Decision;
use App\Models\FieldJobSetting;
use App\Models\Segment;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Inertia\Testing\AssertableInertia as Assert;
use Tests\TestCase;

class FieldJobIndexFilterTest extends TestCase
{
    use RefreshDatabase;

    public function test_shows_only_contracts_in_primary_or_queue_segments(): void
    {
        $user = User::factory()->create();
        $this->actingAs($user);

        $primary = Segment::factory()->create();
        $queue = Segment::factory()->create();

        FieldJobSetting::query()->create([
            'segment_id' => $primary->id,
            'initial_decision_id' => Decision::factory()->create()->id,
            'assign_decision_id' => Decision::factory()->create()->id,
            'complete_decision_id' => Decision::factory()->create()->id,
            'queue_segment_id' => $queue->id,
        ]);

        $case = ClientCase::factory()->create();

        $inPrimary = Contract::factory()->create(['client_case_id' => $case->id]);
        $inQueue = Contract::factory()->create(['client_case_id' => $case->id]);
        $inOther = Contract::factory()->create(['client_case_id' => $case->id]);

        DB::table('contract_segment')->insert([
            ['contract_id' => $inPrimary->id, 'segment_id' => $primary->id, 'active' => true, 'created_at' => now(), 'updated_at' => now()],
            ['contract_id' => $inQueue->id, 'segment_id' => $queue->id, 'active' => true, 'created_at' => now(), 'updated_at' => now()],
            ['contract_id' => $inOther->id, 'segment_id' => Segment::factory()->create()->id, 'active' => true, 'created_at' => now(), 'updated_at' => now()],
        ]);

        $response = $this->get(route('fieldjobs.index'));
        $response->assertStatus(200);

        $response->assertInertia(function (Assert $page) use ($inPrimary, $inQueue, $inOther) {
            $contracts = collect($page->toArray()['props']['contracts']);
            $uuids = $contracts->pluck('uuid')->all();

            $this->assertContains($inPrimary->uuid, $uuids);
            $this->assertContains($inQueue->uuid, $uuids);
            $this->assertNotContains($inOther->uuid, $uuids);
        });
    }

    public function test_returns_no_contracts_when_there_is_no_field_job_setting(): void
    {
        $user = User::factory()->create();
        $this->actingAs($user);

        $case = ClientCase::factory()->create();
        $contract = Contract::factory()->create(['client_case_id' => $case->id]);

        $seg = Segment::factory()->create();
        DB::table('contract_segment')->insert([
            'contract_id' => $contract->id, 'segment_id' => $seg->id, 'active' => true, 'created_at' => now(), 'updated_at' => now(),
        ]);

        $response = $this->get(route('fieldjobs.index'));
        $response->assertStatus(200);

        $response->assertInertia(function (Assert $page) {
            $contracts = collect($page->toArray()['props']['contracts']);
            $this->assertTrue($contracts->isEmpty());
        });
    }

    public function test_returns_no_contracts_when_setting_has_no_segments_configured(): void
    {
        $user = User::factory()->create();
        $this->actingAs($user);

        FieldJobSetting::query()->create([
            'segment_id' => null,
            'queue_segment_id' => null,
            'initial_decision_id' => Decision::factory()->create()->id,
            'assign_decision_id' => Decision::factory()->create()->id,
            'complete_decision_id' => Decision::factory()->create()->id,
        ]);

        $case = ClientCase::factory()->create();
        $contract = Contract::factory()->create(['client_case_id' => $case->id]);

        $seg = Segment::factory()->create();
        DB::table('contract_segment')->insert([
            'contract_id' => $contract->id, 'segment_id' => $seg->id, 'active' => true, 'created_at' => now(), 'updated_at' => now(),
        ]);

        $response = $this->get(route('fieldjobs.index'));
        $response->assertStatus(200);

        $response->assertInertia(function (Assert $page) {
            $contracts = collect($page->toArray()['props']['contracts']);
            $this->assertTrue($contracts->isEmpty());
        });
    }

    public function test_cancelling_moves_contract_to_queue_segment(): void
    {
        $user = User::factory()->create();
        $this->actingAs($user);

        $primary = Segment::factory()->create();
        $queue = Segment::factory()->create();

        $setting = FieldJobSetting::query()->create([
            'segment_id' => $primary->id,
            'queue_segment_id' => $queue->id,
            'initial_decision_id' => Decision::factory()->create()->id,
            'assign_decision_id' => Decision::factory()->create()->id,
            'complete_decision_id' => Decision::factory()->create()->id,
        ]);

        $case = ClientCase::factory()->create();
        $contract = Contract::factory()->create(['client_case_id' => $case->id]);

        // Ensure contract is in primary segment initially
        DB::table('contract_segment')->insert([
            'contract_id' => $contract->id, 'segment_id' => $primary->id, 'active' => true, 'created_at' => now(), 'updated_at' => now(),
        ]);

        // Create an active field job for the contract
        \App\Models\FieldJob::create([
            'field_job_setting_id' => $setting->id,
            'assigned_user_id' => $user->id,
            'contract_id' => $contract->id,
            'assigned_at' => now(),
        ]);

        // Cancel via controller route
        $response = $this->post(route('fieldjobs.cancel'), [
            'contract_uuid' => $contract->uuid,
        ]);

        $response->assertSessionHasNoErrors();

        // After cancellation, the model hook should move the contract to queue segment (ensure pivot exists and active)
        $pivot = DB::table('contract_segment')
            ->where('contract_id', $contract->id)
            ->where('segment_id', $queue->id)
            ->first();

        $this->assertNotNull($pivot, 'Queue segment pivot should be created/ensured');
        $this->assertTrue((bool) $pivot->active, 'Queue segment pivot should be active');
    }
}
