<?php

namespace Tests\Feature\BranchIsolation;

use App\Models\Branch;
use App\Models\Business;
use App\Models\Role;
use App\Models\Task;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class Phase8TaskControllerScopeTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed(DatabaseSeeder::class);
    }

    public function test_primary_only_manager_can_scope_tasks_and_assign_primary_only_staff_without_pivots(): void
    {
        $business = Business::firstOrFail();
        $branchA = Branch::create(['business_id'=>$business->id,'name'=>'Phase 8 Tasks A','status'=>'active']);
        $branchB = Branch::create(['business_id'=>$business->id,'name'=>'Phase 8 Tasks B','status'=>'active']);

        $manager = $this->primaryOnlyStaff('branch-manager',$branchA,'phase8_task_manager_a');
        $officerA = $this->primaryOnlyStaff('loan-officer',$branchA,'phase8_task_officer_a');
        $officerB = $this->primaryOnlyStaff('loan-officer',$branchB,'phase8_task_officer_b');

        $this->assertSame([], $manager->branches()->pluck('branches.id')->all());
        $this->assertSame([], $officerA->branches()->pluck('branches.id')->all());

        Task::create([
            'branch_id'=>$branchA->id,'title'=>'Phase 8 Branch A Task','category'=>'general','priority'=>'normal','status'=>'pending',
            'assigned_to'=>$officerA->id,'created_by'=>$manager->id,
        ]);
        Task::create([
            'branch_id'=>$branchB->id,'title'=>'Phase 8 Branch B Task','category'=>'general','priority'=>'normal','status'=>'pending',
            'assigned_to'=>$officerB->id,'created_by'=>$officerB->id,
        ]);

        $this->actingAs($manager)->get(route('tasks.index'))
            ->assertOk()
            ->assertSee('Phase 8 Branch A Task')
            ->assertDontSee('Phase 8 Branch B Task')
            ->assertSee($branchA->name)
            ->assertDontSee($branchB->name);

        $this->actingAs($manager)->get(route('tasks.create'))
            ->assertOk()
            ->assertSee($branchA->name)
            ->assertDontSee($branchB->name)
            ->assertSee($officerA->name)
            ->assertDontSee($officerB->name);

        $response = $this->actingAs($manager)->post(route('tasks.store'),[
            'branch_id'=>$branchA->id,
            'assigned_to'=>$officerA->id,
            'title'=>'Assigned through primary branch',
            'category'=>'general',
            'priority'=>'normal',
        ]);

        $created = Task::where('title','Assigned through primary branch')->firstOrFail();
        $response->assertRedirect(route('tasks.show',$created));
        $this->assertSame($branchA->id,$created->branch_id);
        $this->assertSame($officerA->id,$created->assigned_to);

        $this->actingAs($manager)->post(route('tasks.store'),[
            'branch_id'=>$branchA->id,
            'assigned_to'=>$officerB->id,
            'title'=>'Cross branch primary assignment',
            'category'=>'general',
            'priority'=>'normal',
        ])->assertStatus(422);
    }

    private function primaryOnlyStaff(string $role, Branch $branch, string $username): User
    {
        $user = User::factory()->create([
            'name'=>str($username)->replace('_',' ')->title()->toString(),
            'username'=>$username,
            'status'=>'active',
            'primary_branch_id'=>$branch->id,
        ]);
        $user->roles()->attach(Role::where('name',$role)->firstOrFail());
        return $user;
    }
}
