<?php

namespace Tests\Feature;

use App\Models\Branch;
use App\Models\Business;
use App\Models\Collateral;
use App\Models\CollateralCategory;
use App\Models\Customer;
use App\Models\FinancialAccount;
use App\Models\Loan;
use App\Models\LoanPayment;
use App\Models\LoanProduct;
use App\Models\LoanRestructuring;
use App\Models\LoanTopUp;
use App\Models\LoanWriteOff;
use App\Models\LoanWriteOffRecovery;
use App\Models\Role;
use App\Models\User;
use App\Services\LoanBranchReportService;
use Carbon\CarbonImmutable;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class LoanBranchReportsWorkflowTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        CarbonImmutable::setTestNow('2026-08-12 13:45:00');
        $this->seed(DatabaseSeeder::class);
        $this->actingAs(User::where('username','admin')->firstOrFail());
    }

    protected function tearDown(): void
    {
        CarbonImmutable::setTestNow();
        parent::tearDown();
    }

    public function test_portfolio_principal_interest_due_and_overdue_reports_reconcile_current_loan_state(): void
    {
        [$branch,$account,$product,$officer] = $this->fixture('portfolio');
        $customerA = $this->customer($branch,'portfolio-a');
        $customerB = $this->customer($branch,'portfolio-b');
        $loanA = $this->loan($branch,$customerA,$product,$officer,'PORT-A',[
            'principal'=>'100000.00','interest'=>'10000.00','total_repayment'=>'110000.00','principal_outstanding'=>'80000.00',
            'interest_outstanding'=>'8000.00','total_outstanding'=>'88000.00','total_paid'=>'22000.00','overdue_principal'=>'20000.00',
            'overdue_interest'=>'2000.00','total_overdue'=>'22000.00','days_overdue'=>10,'arrears_bucket'=>'8-30 days',
        ]);
        $loanA->installments()->create([
            'installment_number'=>1,'principal'=>'50000.00','interest'=>'5000.00','fees'=>'0.00','amount_due'=>'55000.00','due_date'=>'2026-08-12',
            'amount_paid'=>'10000.00','remaining'=>'45000.00','status'=>'partial','principal_paid'=>'10000.00','interest_paid'=>'0.00','fees_paid'=>'0.00','penalty_due'=>'0.00','penalty_paid'=>'0.00',
        ]);
        $loanB = $this->loan($branch,$customerB,$product,$officer,'PORT-B',[
            'principal'=>'60000.00','interest'=>'6000.00','total_repayment'=>'66000.00','principal_outstanding'=>'50000.00',
            'interest_outstanding'=>'5000.00','total_outstanding'=>'55000.00','total_paid'=>'11000.00',
        ]);
        $loanB->installments()->create([
            'installment_number'=>1,'principal'=>'60000.00','interest'=>'6000.00','fees'=>'0.00','amount_due'=>'66000.00','due_date'=>'2026-09-12',
            'amount_paid'=>'11000.00','remaining'=>'55000.00','status'=>'partial','principal_paid'=>'10000.00','interest_paid'=>'1000.00','fees_paid'=>'0.00','penalty_due'=>'0.00','penalty_paid'=>'0.00',
        ]);

        $service = app(LoanBranchReportService::class);
        $portfolio = $service->generate('active-loan-portfolio',[$branch->id],'2026-08-01','2026-08-12');
        $principal = $service->generate('outstanding-principal',[$branch->id],'2026-08-01','2026-08-12');
        $interest = $service->generate('outstanding-interest',[$branch->id],'2026-08-01','2026-08-12');
        $due = $service->generate('due-today',[$branch->id],'2026-08-01','2026-08-12');
        $overdue = $service->generate('overdue-loans',[$branch->id],'2026-08-01','2026-08-12',['arrears_bucket'=>'8-30 days']);

        $this->assertSame('2',$this->summary($portfolio,'Active loans'));
        $this->assertSame('130000.00',$this->summary($portfolio,'Outstanding principal'));
        $this->assertSame('143000.00',$this->summary($portfolio,'Total outstanding'));
        $this->assertSame('130000.00',$this->summary($principal,'Outstanding principal'));
        $this->assertSame('13000.00',$this->summary($interest,'Outstanding interest'));
        $this->assertCount(1,$due['rows']);
        $this->assertSame('45000.00',$this->summary($due,'Remaining due'));
        $this->assertSame($loanA->loan_number,$due['rows'][0]['loan_number']);
        $this->assertCount(1,$overdue['rows']);
        $this->assertSame('22000.00',$this->summary($overdue,'Total overdue'));
        $this->assertSame($loanA->loan_number,$overdue['rows'][0]['loan_number']);
        $this->assertSame('Cash '.str('portfolio')->headline(),$account->name);
    }

    public function test_completed_written_off_collateral_top_up_restructuring_and_recovery_reports_use_permanent_records(): void
    {
        [$branch,$account,$product,$officer] = $this->fixture('lifecycle');
        $manager = $this->staff('branch-manager',$branch,'lifecycle_manager');
        $customer = $this->customer($branch,'lifecycle');

        $completed = $this->loan($branch,$customer,$product,$officer,'COMP',[
            'status'=>'completed','principal'=>'90000.00','interest'=>'9000.00','total_repayment'=>'99000.00','principal_outstanding'=>'0.00',
            'interest_outstanding'=>'0.00','total_outstanding'=>'0.00','total_paid'=>'99000.00','completed_at'=>'2026-08-05 10:00:00',
        ]);
        $written = $this->loan($branch,$customer,$product,$officer,'WRITE',[
            'status'=>'written_off','principal'=>'50000.00','interest'=>'5000.00','total_repayment'=>'55000.00','principal_outstanding'=>'40000.00',
            'interest_outstanding'=>'5000.00','total_outstanding'=>'45000.00','written_off_at'=>'2026-08-06 09:00:00','written_off_by'=>$manager->id,
        ]);
        $writeOff = LoanWriteOff::create([
            'write_off_number'=>'WOF-REPORT-001','loan_id'=>$written->id,'customer_id'=>$customer->id,'branch_id'=>$branch->id,
            'original_principal'=>'50000.00','original_total_repayment'=>'55000.00','principal_outstanding'=>'40000.00','interest_outstanding'=>'5000.00',
            'fees_outstanding'=>'0.00','penalties_outstanding'=>'0.00','write_off_amount'=>'45000.00','recovered_amount'=>'10000.00','recoverable_balance'=>'35000.00',
            'reason'=>'Exhausted collection process','status'=>'approved','requested_by'=>$manager->id,'requested_at'=>'2026-08-05 09:00:00','approved_by'=>$manager->id,'approved_at'=>'2026-08-06 09:00:00',
        ]);
        LoanWriteOffRecovery::create([
            'recovery_number'=>'WOR-REPORT-001','loan_write_off_id'=>$writeOff->id,'loan_id'=>$written->id,'customer_id'=>$customer->id,'branch_id'=>$branch->id,
            'financial_account_id'=>$account->id,'amount'=>'10000.00','recovery_date'=>'2026-08-08 11:00:00','method'=>'cash','reference'=>'RECOVERY-001','received_by'=>$manager->id,
        ]);

        $old = $this->loan($branch,$customer,$product,$officer,'TOP-OLD',['status'=>'closed_through_top_up','total_outstanding'=>'0.00','principal_outstanding'=>'0.00']);
        $new = $this->loan($branch,$customer,$product,$officer,'TOP-NEW',['principal'=>'120000.00','interest'=>'12000.00','total_repayment'=>'132000.00','principal_outstanding'=>'120000.00','interest_outstanding'=>'12000.00','total_outstanding'=>'132000.00']);
        LoanTopUp::create([
            'top_up_number'=>'TOP-REPORT-001','branch_id'=>$branch->id,'previous_loan_id'=>$old->id,'new_loan_id'=>$new->id,'financial_account_id'=>$account->id,
            'previous_outstanding'=>'20000.00','previous_principal'=>'20000.00','previous_interest'=>'0.00','previous_fees'=>'0.00','previous_penalties'=>'0.00',
            'amount_settled_internally'=>'20000.00','new_principal'=>'120000.00','new_interest'=>'12000.00','new_fees'=>'0.00','new_total_repayment'=>'132000.00',
            'cash_given_to_customer'=>'100000.00','top_up_date'=>'2026-08-09','reference'=>'TOPUP-REPORT','executed_by'=>$manager->id,
        ]);
        LoanRestructuring::create([
            'restructuring_number'=>'RST-REPORT-001','loan_id'=>$new->id,'branch_id'=>$branch->id,'previous_schedule_version'=>1,'new_schedule_version'=>2,
            'principal_outstanding'=>'120000.00','interest_outstanding'=>'12000.00','fees_outstanding'=>'0.00','penalties_outstanding'=>'0.00','total_outstanding'=>'132000.00',
            'previous_schedule'=>[['installment_number'=>1]],'new_schedule'=>[['installment_number'=>1]],'reason'=>'Customer cash-flow change','status'=>'approved',
            'requested_by'=>$manager->id,'requested_at'=>'2026-08-10 08:00:00','approved_by'=>$manager->id,'approved_at'=>'2026-08-10 09:00:00',
        ]);

        $category = CollateralCategory::where('business_id',$branch->business_id)->firstOrFail();
        $collateral = Collateral::create([
            'customer_id'=>$customer->id,'branch_id'=>$branch->id,'category_id'=>$category->id,'sequence_number'=>1,'code'=>'COL-REPORT-001','item'=>'Television',
            'serial_number'=>'SN-REPORT-001','estimated_value'=>'80000.00','accepted_value'=>'60000.00','received_at'=>'2026-07-01','store_room'=>'Store A','shelf'=>'S1',
            'status'=>'in_custody','received_by'=>$manager->id,'created_by'=>$manager->id,
        ]);
        $new->collaterals()->attach($collateral->id);

        $service = app(LoanBranchReportService::class);
        $completedReport = $service->generate('completed-loans',[$branch->id],'2026-08-01','2026-08-12');
        $writtenReport = $service->generate('written-off-loans',[$branch->id],'2026-08-01','2026-08-12');
        $topUpReport = $service->generate('top-up-report',[$branch->id],'2026-08-01','2026-08-12');
        $restructureReport = $service->generate('restructuring-report',[$branch->id],'2026-08-01','2026-08-12');
        $collateralReport = $service->generate('collateral-report',[$branch->id],'2026-08-01','2026-08-12',['record_status'=>'in_custody']);
        $recoveryReport = $service->generate('write-off-recovery-report',[$branch->id],'2026-08-01','2026-08-12');

        $this->assertSame($completed->loan_number,$completedReport['rows'][0]['loan_number']);
        $this->assertSame('99000.00',$this->summary($completedReport,'Total paid'));
        $this->assertSame('45000.00',$this->summary($writtenReport,'Write-off amount'));
        $this->assertSame('10000.00',$this->summary($writtenReport,'Recovered'));
        $this->assertSame('100000.00',$this->summary($topUpReport,'Cash given'));
        $this->assertSame('1',$this->summary($restructureReport,'Approved'));
        $this->assertSame('60000.00',$this->summary($collateralReport,'Accepted value'));
        $this->assertSame($new->loan_number,$collateralReport['rows'][0]['loans']);
        $this->assertSame('10000.00',$this->summary($recoveryReport,'Recovered in period'));
        $this->assertSame('35000.00',$this->summary($recoveryReport,'Current recoverable balance'));
    }

    public function test_collection_rate_branch_and_company_performance_reconcile_scheduled_due_and_collections(): void
    {
        [$branchA,$accountA,$productA,$officerA] = $this->fixture('branch-a');
        [$branchB,$accountB,$productB,$officerB] = $this->fixture('branch-b');
        $loanA = $this->loan($branchA,$this->customer($branchA,'rate-a'),$productA,$officerA,'RATE-A',[
            'principal'=>'1000.00','interest'=>'0.00','total_repayment'=>'1000.00','principal_outstanding'=>'920.00','interest_outstanding'=>'0.00','total_outstanding'=>'920.00','total_paid'=>'80.00','disbursed_at'=>'2026-08-01 08:00:00',
        ]);
        $loanA->installments()->create(['installment_number'=>1,'principal'=>'100.00','interest'=>'0.00','fees'=>'0.00','amount_due'=>'100.00','due_date'=>'2026-08-10','amount_paid'=>'80.00','remaining'=>'20.00','status'=>'partial','principal_paid'=>'80.00','interest_paid'=>'0.00','fees_paid'=>'0.00','penalty_due'=>'0.00','penalty_paid'=>'0.00']);
        LoanPayment::create(['receipt_number'=>'REC-RATE-A','loan_id'=>$loanA->id,'customer_id'=>$loanA->customer_id,'branch_id'=>$branchA->id,'financial_account_id'=>$accountA->id,'amount'=>'80.00','principal_amount'=>'80.00','payment_date'=>'2026-08-10 09:00:00','method'=>'cash','received_by'=>$officerA->id]);

        $loanB = $this->loan($branchB,$this->customer($branchB,'rate-b'),$productB,$officerB,'RATE-B',[
            'principal'=>'2000.00','interest'=>'0.00','total_repayment'=>'2000.00','principal_outstanding'=>'1900.00','interest_outstanding'=>'0.00','total_outstanding'=>'1900.00','total_paid'=>'100.00','disbursed_at'=>'2026-08-02 08:00:00',
        ]);
        $loanB->installments()->create(['installment_number'=>1,'principal'=>'200.00','interest'=>'0.00','fees'=>'0.00','amount_due'=>'200.00','due_date'=>'2026-08-11','amount_paid'=>'100.00','remaining'=>'100.00','status'=>'partial','principal_paid'=>'100.00','interest_paid'=>'0.00','fees_paid'=>'0.00','penalty_due'=>'0.00','penalty_paid'=>'0.00']);
        LoanPayment::create(['receipt_number'=>'REC-RATE-B','loan_id'=>$loanB->id,'customer_id'=>$loanB->customer_id,'branch_id'=>$branchB->id,'financial_account_id'=>$accountB->id,'amount'=>'100.00','principal_amount'=>'100.00','payment_date'=>'2026-08-11 09:00:00','method'=>'cash','received_by'=>$officerB->id]);

        $service = app(LoanBranchReportService::class);
        $scope = [$branchA->id,$branchB->id];
        $rate = $service->generate('loan-collection-rate',$scope,'2026-08-01','2026-08-12');
        $branchPerformance = $service->generate('branch-performance',$scope,'2026-08-01','2026-08-12');
        $company = $service->generate('company-performance',$scope,'2026-08-01','2026-08-12');

        $this->assertSame('300.00',$this->summary($rate,'Scheduled due'));
        $this->assertSame('180.00',$this->summary($rate,'Collected'));
        $this->assertSame('60.00',$this->summary($rate,'Collection rate'));
        $this->assertCount(2,$branchPerformance['rows']);
        $rowA = collect($branchPerformance['rows'])->firstWhere('branch',$branchA->name);
        $rowB = collect($branchPerformance['rows'])->firstWhere('branch',$branchB->name);
        $this->assertSame('80.00',$rowA['collection_rate']);
        $this->assertSame('50.00',$rowB['collection_rate']);
        $this->assertSame('3000.00',$this->summary($branchPerformance,'Period disbursed'));
        $this->assertSame('180.00',$this->summary($branchPerformance,'Period collections'));
        $this->assertSame('2820.00',$this->summary($company,'Current portfolio'));
        $this->assertSame('60.00',$this->summary($company,'Collection rate'));
    }

    public function test_loan_officer_performance_and_filters_attribute_loans_to_the_recorded_originator(): void
    {
        [$branch,$account,$product,$officerA] = $this->fixture('officers');
        $officerB = $this->staff('loan-officer',$branch,'reports_officer_b');
        $loanA = $this->loan($branch,$this->customer($branch,'officer-a'),$product,$officerA,'OFF-A',['principal'=>'1000.00','interest'=>'0.00','total_repayment'=>'1000.00','principal_outstanding'=>'900.00','interest_outstanding'=>'0.00','total_outstanding'=>'900.00','total_paid'=>'100.00']);
        $loanA->installments()->create(['installment_number'=>1,'principal'=>'100.00','interest'=>'0.00','fees'=>'0.00','amount_due'=>'100.00','due_date'=>'2026-08-10','amount_paid'=>'100.00','remaining'=>'0.00','status'=>'paid','principal_paid'=>'100.00','interest_paid'=>'0.00','fees_paid'=>'0.00','penalty_due'=>'0.00','penalty_paid'=>'0.00']);
        LoanPayment::create(['receipt_number'=>'REC-OFF-A','loan_id'=>$loanA->id,'customer_id'=>$loanA->customer_id,'branch_id'=>$branch->id,'financial_account_id'=>$account->id,'amount'=>'100.00','principal_amount'=>'100.00','payment_date'=>'2026-08-10 09:00:00','method'=>'cash','received_by'=>$officerA->id]);
        $loanB = $this->loan($branch,$this->customer($branch,'officer-b'),$product,$officerB,'OFF-B',['principal'=>'2000.00','interest'=>'0.00','total_repayment'=>'2000.00','principal_outstanding'=>'2000.00','interest_outstanding'=>'0.00','total_outstanding'=>'2000.00']);
        $loanB->installments()->create(['installment_number'=>1,'principal'=>'200.00','interest'=>'0.00','fees'=>'0.00','amount_due'=>'200.00','due_date'=>'2026-08-10','amount_paid'=>'0.00','remaining'=>'200.00','status'=>'upcoming','principal_paid'=>'0.00','interest_paid'=>'0.00','fees_paid'=>'0.00','penalty_due'=>'0.00','penalty_paid'=>'0.00']);

        $service = app(LoanBranchReportService::class);
        $all = $service->generate('loan-officer-performance',[$branch->id],'2026-08-01','2026-08-12');
        $filtered = $service->generate('loan-officer-performance',[$branch->id],'2026-08-01','2026-08-12',['loan_officer_id'=>$officerA->id]);
        $search = $service->generate('active-loan-portfolio',[$branch->id],'2026-08-01','2026-08-12',['search'=>$loanB->loan_number]);

        $this->assertCount(2,$all['rows']);
        $rowA = collect($all['rows'])->firstWhere('officer',$officerA->name);
        $rowB = collect($all['rows'])->firstWhere('officer',$officerB->name);
        $this->assertSame('100.00',$rowA['collections']);
        $this->assertSame('100.00',$rowA['collection_rate']);
        $this->assertSame('0.00',$rowB['collection_rate']);
        $this->assertCount(1,$filtered['rows']);
        $this->assertSame($officerA->name,$filtered['rows'][0]['officer']);
        $this->assertCount(1,$search['rows']);
        $this->assertSame($loanB->loan_number,$search['rows'][0]['loan_number']);
    }

    public function test_report_routes_enforce_report_permission_and_branch_scope(): void
    {
        [$branchA,,,$officerA] = $this->fixture('security-a');
        [$branchB,,,$officerB] = $this->fixture('security-b');
        $loanA = $this->loan($branchA,$this->customer($branchA,'security-a'),$this->productFor($branchA),$officerA,'SEC-A');
        $loanB = $this->loan($branchB,$this->customer($branchB,'security-b'),$this->productFor($branchB),$officerB,'SEC-B');
        $auditorA = $this->staff('auditor',$branchA,'step20_auditor_a');
        $cashierA = $this->staff('cashier',$branchA,'step20_cashier_a');

        $this->actingAs($auditorA)->get(route('loan-branch-reports.index',['report'=>'active-loan-portfolio','branch_ids'=>[$branchB->id]]))->assertForbidden();
        $this->actingAs($auditorA)->get(route('loan-branch-reports.index',['report'=>'active-loan-portfolio','search'=>$loanA->loan_number]))
            ->assertOk()->assertSee($loanA->loan_number)->assertDontSee($loanB->loan_number);
        $this->actingAs($cashierA)->get(route('loan-branch-reports.index'))->assertForbidden();
    }

    public function test_all_fifteen_reports_render_and_export_the_same_permission_scoped_workspace(): void
    {
        [$branch] = $this->fixture('ui');
        $auditor = $this->staff('auditor',$branch,'step20_ui_auditor');

        foreach (LoanBranchReportService::REPORTS as $slug=>$title) {
            $this->actingAs($auditor)->get(route('loan-branch-reports.index',['report'=>$slug,'from'=>'2026-08-01','to'=>'2026-08-12']))
                ->assertOk()->assertSee($title)->assertSee('Export CSV');
            $export = $this->actingAs($auditor)->get(route('loan-branch-reports.export',['report'=>$slug,'from'=>'2026-08-01','to'=>'2026-08-12']));
            $export->assertOk();
            $this->assertStringContainsString('text/csv',(string)$export->headers->get('content-type'));
            $this->assertStringContainsString($title,$export->streamedContent());
        }

        $this->actingAs($auditor)->get(route('loan-branch-reports.index'))->assertOk()->assertSee('Loan &amp; Branch Reports',false);
    }

    private function fixture(string $tag): array
    {
        $business = Business::firstOrFail();
        $branch = Branch::create(['business_id'=>$business->id,'name'=>'Step20 '.str($tag)->headline(),'status'=>'active']);
        $account = FinancialAccount::create(['branch_id'=>$branch->id,'name'=>'Cash '.str($tag)->headline(),'account_type'=>'cash','opening_balance'=>'1000000.00','current_balance'=>'1000000.00','status'=>'active']);
        $product = $this->product($business,'Step20 Product '.str($tag)->headline());
        $officer = $this->staff('loan-officer',$branch,'step20_officer_'.$tag);
        return [$branch,$account,$product,$officer];
    }

    private function productFor(Branch $branch): LoanProduct
    {
        return LoanProduct::where('business_id',$branch->business_id)->firstOrFail();
    }

    private function product(Business $business, string $name): LoanProduct
    {
        return LoanProduct::create([
            'business_id'=>$business->id,'name'=>$name,'minimum_amount'=>'100.00','maximum_amount'=>'1000000.00','duration'=>2,'duration_unit'=>'months',
            'interest_rate'=>'10.000000','interest_calculation_method'=>'flat','repayment_frequency'=>'monthly','grace_period_days'=>0,
            'late_payment_penalty_type'=>'none','late_payment_penalty_value'=>'0.000000','processing_fee_type'=>'fixed','processing_fee_value'=>'0.000000',
            'insurance_fee_type'=>'fixed','insurance_fee_value'=>'0.000000','other_charges'=>'0.00','collateral_required'=>false,'guarantor_required'=>false,'status'=>'active',
        ]);
    }

    private function customer(Branch $branch, string $tag): Customer
    {
        return Customer::create([
            'branch_id'=>$branch->id,'customer_number'=>'CUS-S20-'.strtoupper(substr(md5($branch->id.$tag),0,10)),'identity_mode'=>'without_nin',
            'first_name'=>'Customer','last_name'=>str($tag)->headline()->toString(),'phone'=>'07'.str_pad((string)(Customer::count()+1),8,'0',STR_PAD_LEFT),'status'=>'active',
        ]);
    }

    private function loan(Branch $branch, Customer $customer, LoanProduct $product, User $officer, string $tag, array $overrides = []): Loan
    {
        $sequence = Loan::where('branch_id',$branch->id)->count()+1;
        $defaults = [
            'branch_id'=>$branch->id,'customer_id'=>$customer->id,'loan_product_id'=>$product->id,'sequence_number'=>$sequence,'sequence_year'=>2026,
            'loan_number'=>'LN-S20-'.strtoupper($tag).'-'.$branch->id.'-'.$sequence,'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','principal_outstanding'=>'100000.00',
            'interest_outstanding'=>'10000.00','fees_outstanding'=>'0.00','penalties_outstanding'=>'0.00','total_outstanding'=>'110000.00','total_paid'=>'0.00',
            'overdue_principal'=>'0.00','overdue_interest'=>'0.00','overdue_fees'=>'0.00','overdue_penalties'=>'0.00','total_overdue'=>'0.00','days_overdue'=>0,
            'late_payment_penalty_type'=>'none','late_payment_penalty_value'=>'0.000000','purpose'=>'Step 20 report fixture','schedule_start_date'=>'2026-08-01',
            'status'=>'active','disbursed_at'=>'2026-08-01 08:00:00','activated_at'=>'2026-08-01 08:00:00','schedule_activated_at'=>'2026-08-01 08:00:00','created_by'=>$officer->id,
        ];
        return Loan::create(array_merge($defaults,$overrides));
    }

    private function staff(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());
        $user->branches()->attach($branch->id,['is_primary'=>true]);
        return $user;
    }

    private function summary(array $report, string $label): string
    {
        return (string) collect($report['summary'])->firstWhere('label',$label)['value'];
    }
}
