<?php

namespace Tests\App\Libraries;

use App\Libraries\Tuition\TuitionForecastService;
use CodeIgniter\Test\CIUnitTestCase;

class TuitionForecastServiceTest extends CIUnitTestCase
{
    public function testForecastSubtractsAlreadyCollectedAndKeepsEventOnlyStudentsNonBillable(): void
    {
        $service = new class () extends TuitionForecastService {
            public function __construct()
            {
                parent::__construct();
            }

            protected function getDefaultSchoolYear(): string
            {
                return '2025-2026';
            }

            protected function getDefaultSemester(): string
            {
                return '';
            }

            protected function loadFamilies(string $schoolYear, string $semester): array
            {
                return [
                    ['parent_id' => 10, 'parent_name' => 'Yusuf, Layla'],
                ];
            }

            protected function loadFamilyStudents(int $parentId, string $schoolYear, string $semester, array $options): array
            {
                return [
                    'students' => [
                        ['student_id' => 1, 'student_name' => 'Mariam', 'grade_level' => '1'],
                        ['student_id' => 2, 'student_name' => 'Yahya', 'grade_level' => '2'],
                        ['student_id' => 4, 'student_name' => 'Youth Student', 'grade_level' => 'Youth 1'],
                    ],
                    'all_students' => [
                        ['student_id' => 1, 'student_name' => 'Mariam', 'grade_level' => '1', 'billable' => true, 'excluded_reason' => null],
                        ['student_id' => 2, 'student_name' => 'Yahya', 'grade_level' => '2', 'billable' => true, 'excluded_reason' => null],
                        ['student_id' => 4, 'student_name' => 'Youth Student', 'grade_level' => 'Youth 1', 'billable' => true, 'excluded_reason' => null],
                        ['student_id' => 3, 'student_name' => 'Event Only', 'grade_level' => '3', 'billable' => false, 'excluded_reason' => 'event_only'],
                    ],
                    'warnings' => ['1 event-only student(s) excluded from tuition.'],
                ];
            }

            protected function getTuitionConfig(): array
            {
                return [
                    'grade_fee' => 9,
                    'first_student_fee' => '350.00',
                    'second_student_fee' => '200.00',
                    'youth_fee' => '200.00',
                    'new_tuition_full_amount' => $this->unitPriceOverride ?? '350.00',
                    'new_tuition_youth_amount' => $this->youthUnitPriceOverride ?? '200.00',
                    'new_tuition_second_student_discount' => '50.00',
                    'new_tuition_third_student_discount' => '50.00',
                    'new_tuition_fourth_plus_discount' => '100.00',
                ];
            }
        };

        $result = $service->calculate('2025-2026', 'Fall', 'compare', [
            'include_payment_pending' => true,
            'include_withdrawn_mode' => 'refund_deadline',
            'unit_price' => '400.00',
            'youth_unit_price' => '200.00',
        ]);

        $this->assertSame(1, $result['summary']['family_count']);
        $this->assertSame(4, $result['summary']['student_count']);
        $this->assertSame(3, $result['summary']['billable_student_count']);
        $this->assertSame('750.00', $result['summary']['old_projected_tuition']);
        $this->assertSame('950.00', $result['summary']['new_projected_tuition']);
        $this->assertSame('750.00', $result['summary']['old_projected_income']);
        $this->assertSame('950.00', $result['summary']['new_projected_income']);
        $this->assertSame('400.00', $result['summary']['unit_price']);
        $this->assertSame('200.00', $result['summary']['youth_unit_price']);
        $this->assertSame('event_only', $result['families'][0]['student_details'][3]['excluded_reason']);
    }
}
