<?php

namespace Tests\Feature\BranchIsolation;

use App\Models\Branch;
use App\Models\Business;
use App\Models\Collateral;
use App\Models\CollateralCategory;
use App\Models\CollateralFile;
use App\Models\CollateralMovement;
use App\Models\Customer;
use App\Models\CustomerDocument;
use App\Models\Loan;
use App\Models\LoanDocument;
use App\Models\LoanProduct;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class IndirectChildScopeTest extends TestCase
{
    use RefreshDatabase;

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

    public function test_indirect_child_records_follow_their_parent_branch_scope(): void
    {
        $business = Business::firstOrFail();
        $branchA = Branch::factory()->create(['business_id' => $business->id, 'name' => 'Phase 4 A']);
        $branchB = Branch::factory()->create(['business_id' => $business->id, 'name' => 'Phase 4 B']);

        $customerA = Customer::factory()->create(['branch_id' => $branchA->id]);
        $customerB = Customer::factory()->create(['branch_id' => $branchB->id]);
        $product = LoanProduct::factory()->create(['business_id' => $business->id]);

        $loanA = $this->loan($branchA, $customerA, $product, 'LON-P4-A');
        $loanB = $this->loan($branchB, $customerB, $product, 'LON-P4-B');

        $category = CollateralCategory::create([
            'business_id' => $business->id,
            'name' => 'Phase 4 Security',
            'status' => 'active',
        ]);
        $collateralA = $this->collateral($branchA, $customerA, $category, 'COL-P4-A', 900001);
        $collateralB = $this->collateral($branchB, $customerB, $category, 'COL-P4-B', 900002);

        CustomerDocument::create([
            'customer_id' => $customerA->id,
            'document_type' => 'ID A',
            'original_name' => 'customer-a.pdf',
            'file_path' => 'testing/customer-a.pdf',
        ]);
        CustomerDocument::create([
            'customer_id' => $customerB->id,
            'document_type' => 'ID B',
            'original_name' => 'customer-b.pdf',
            'file_path' => 'testing/customer-b.pdf',
        ]);

        LoanDocument::create([
            'loan_id' => $loanA->id,
            'kind' => 'supporting',
            'document_type' => 'Loan A',
            'original_name' => 'loan-a.pdf',
            'file_path' => 'testing/loan-a.pdf',
        ]);
        LoanDocument::create([
            'loan_id' => $loanB->id,
            'kind' => 'supporting',
            'document_type' => 'Loan B',
            'original_name' => 'loan-b.pdf',
            'file_path' => 'testing/loan-b.pdf',
        ]);

        CollateralFile::create([
            'collateral_id' => $collateralA->id,
            'kind' => 'document',
            'document_type' => 'Ownership A',
            'original_name' => 'collateral-a.pdf',
            'file_path' => 'testing/collateral-a.pdf',
        ]);
        CollateralFile::create([
            'collateral_id' => $collateralB->id,
            'kind' => 'document',
            'document_type' => 'Ownership B',
            'original_name' => 'collateral-b.pdf',
            'file_path' => 'testing/collateral-b.pdf',
        ]);

        CollateralMovement::create([
            'collateral_id' => $collateralA->id,
            'action' => 'received',
            'to_status' => 'in_custody',
            'moved_at' => now(),
        ]);
        CollateralMovement::create([
            'collateral_id' => $collateralB->id,
            'action' => 'received',
            'to_status' => 'in_custody',
            'moved_at' => now(),
        ]);

        $branchAUser = User::factory()->create(['primary_branch_id' => $branchA->id]);
        $branchAUser->branches()->attach($branchA->id, ['is_primary' => true]);

        $this->actingAs($branchAUser);
        $this->assertSame(['customer-a.pdf'], CustomerDocument::pluck('original_name')->all());
        $this->assertSame(['loan-a.pdf'], LoanDocument::pluck('original_name')->all());
        $this->assertSame(['collateral-a.pdf'], CollateralFile::pluck('original_name')->all());
        $this->assertSame([$collateralA->id], CollateralMovement::pluck('collateral_id')->all());

        $multiBranchUser = User::factory()->create(['primary_branch_id' => $branchA->id]);
        $multiBranchUser->branches()->attach([
            $branchA->id => ['is_primary' => true],
            $branchB->id => ['is_primary' => false],
        ]);

        $this->actingAs($multiBranchUser);
        $this->assertSame(2, CustomerDocument::count());
        $this->assertSame(2, LoanDocument::count());
        $this->assertSame(2, CollateralFile::count());
        $this->assertSame(2, CollateralMovement::count());

        $noBranchUser = User::factory()->create(['primary_branch_id' => null]);
        $this->actingAs($noBranchUser);
        $this->assertSame(0, CustomerDocument::count());
        $this->assertSame(0, LoanDocument::count());
        $this->assertSame(0, CollateralFile::count());
        $this->assertSame(0, CollateralMovement::count());

        $superAdmin = User::where('email', 'admin@microfinance.local')->firstOrFail();
        $this->actingAs($superAdmin);
        $this->assertSame(2, CustomerDocument::count());
        $this->assertSame(2, LoanDocument::count());
        $this->assertSame(2, CollateralFile::count());
        $this->assertSame(2, CollateralMovement::count());
    }

    private function loan(Branch $branch, Customer $customer, LoanProduct $product, string $number): Loan
    {
        return Loan::create([
            'branch_id' => $branch->id,
            'customer_id' => $customer->id,
            'loan_product_id' => $product->id,
            'sequence_number' => $branch->id,
            'sequence_year' => 2026,
            'loan_number' => $number,
            'principal' => '100000.00',
            'interest' => '10000.00',
            'processing_fee' => '0.00',
            'insurance_fee' => '0.00',
            'other_charges' => '0.00',
            'fees' => '0.00',
            'total_repayment' => '110000.00',
            'purpose' => 'Phase 4 branch isolation test',
            'schedule_start_date' => '2026-08-14',
            'status' => 'draft',
        ]);
    }

    private function collateral(
        Branch $branch,
        Customer $customer,
        CollateralCategory $category,
        string $code,
        int $sequence,
    ): Collateral {
        return Collateral::create([
            'customer_id' => $customer->id,
            'branch_id' => $branch->id,
            'category_id' => $category->id,
            'sequence_number' => $sequence,
            'code' => $code,
            'item' => 'Phase 4 asset',
            'received_at' => '2026-08-13',
            'status' => 'in_custody',
        ]);
    }
}
