<?php

namespace App\Console\Commands;

use App\Services\DateService;
use Carbon\Carbon;
use Illuminate\Console\Command;

/**
 * Command để test toàn diện DateService
 *
 * Chạy: php artisan test:date-service
 */
class TestDateService extends Command
{
    protected $signature = 'test:date-service';
    protected $description = 'Test tất cả methods trong DateService với các test cases bao trùm';

    private DateService $dateService;
    private int $passCount = 0;
    private int $failCount = 0;

    public function handle()
    {
        $this->dateService = new DateService();

        $this->info("\n" . str_repeat('=', 80));
        $this->info("                    TEST DATESERVICE - COMPREHENSIVE TEST SUITE");
        $this->info(str_repeat('=', 80) . "\n");

        $this->testCalculateMonthsDecimal();
        $this->testCalculateMonthsFloor();
        $this->testCalculateCalendarMonths();
        $this->testCalculateDaysInclusive();
        $this->testCalculateDaysAsMonths();
        $this->testCalculateWorkingYearsDecimal();
        $this->testCalculateWorkingMonths();
        $this->testCalculateWorkingPeriodFormatted();
        $this->testFormatYearsMonths();
        $this->testConvertMonthsToYears();
        $this->testFloorToDecimal();
        $this->testGetOverlappingPeriod();
        $this->testGetFiscalYear();
        $this->testGetFiscalYearStart();
        $this->testGetFiscalYearEnd();

        $this->printSummary();

        return $this->failCount > 0 ? 1 : 0;
    }

    private function printSectionHeader(string $methodName): void
    {
        $this->info("\n" . str_repeat('-', 80));
        $this->info("📌 Testing: {$methodName}()");
        $this->info(str_repeat('-', 80));
    }

    private function assertResult($actual, $expected, string $description): void
    {
        $isPass = false;

        if (is_float($expected) && is_float($actual)) {
            $isPass = abs($actual - $expected) < 0.01;
        } elseif (is_array($expected) && is_array($actual)) {
            $isPass = $this->arraysEqual($actual, $expected);
        } else {
            $isPass = $actual === $expected;
        }

        if ($isPass) {
            $this->passCount++;
            $this->line("  ✅ {$description}");
            $this->line("     → Result: " . $this->formatValue($actual));
        } else {
            $this->failCount++;
            $this->error("  ❌ {$description}");
            $this->error("     → Expected: " . $this->formatValue($expected));
            $this->error("     → Actual:   " . $this->formatValue($actual));
        }
    }

    private function formatValue($value): string
    {
        if ($value === null) {
            return 'null';
        }
        if (is_bool($value)) {
            return $value ? 'true' : 'false';
        }
        if (is_array($value)) {
            return json_encode($value, JSON_UNESCAPED_UNICODE);
        }
        if ($value instanceof Carbon) {
            return $value->format('Y-m-d');
        }
        if (is_float($value)) {
            return number_format($value, 2);
        }
        return (string) $value;
    }

    private function arraysEqual(array $a, array $b): bool
    {
        if (count($a) !== count($b)) {
            return false;
        }
        foreach ($a as $key => $value) {
            if (!isset($b[$key])) {
                return false;
            }
            if ($value instanceof Carbon && $b[$key] instanceof Carbon) {
                if (!$value->isSameDay($b[$key])) {
                    return false;
                }
            } elseif ($value !== $b[$key]) {
                return false;
            }
        }
        return true;
    }

    // ========================================================================
    // TEST: calculateMonthsDecimal()
    // ========================================================================
    private function testCalculateMonthsDecimal(): void
    {
        $this->printSectionHeader('calculateMonthsDecimal');
        $this->line("  Tính số tháng với độ chính xác thập phân (30 days = 1 month)\n");

        // NULL/Edge cases
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal(null, null),
            0.0,
            "NULL inputs → 0.0"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-01-01', null),
            0.0,
            "One NULL input → 0.0"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-03-31', '2024-01-01'),
            0.0,
            "End date before start date → 0.0"
        );

        // Same day
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-01-15', '2024-01-15'),
            0.03,
            "Same day (1 day / 30) → 0.03"
        );

        // Full fiscal year (Japanese standard)
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2015-04-01', '2016-03-31'),
            12.00,
            "Full fiscal year 2015/04/01 → 2016/03/31 → 12.00 months"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2020-04-01', '2021-03-31'),
            12.00,
            "Full fiscal year 2020/04/01 → 2021/03/31 (leap year) → 12.00 months"
        );

        // Partial periods - User's specific examples
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2015-01-23', '2015-03-31'),
            2.27,
            "Partial period 2015/01/23 → 2015/03/31 (2m + 8d) → 2.27 months"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2016-04-01', '2016-04-19'),
            0.63,
            "19 days only 2016/04/01 → 2016/04/19 → 0.63 months"
        );

        // Full months (starting from 1st)
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-01-01', '2024-01-31'),
            1.00,
            "Full January 2024/01/01 → 2024/01/31 → 1.00 month"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-02-01', '2024-02-29'),
            1.00,
            "Full February (leap year) 2024/02/01 → 2024/02/29 → 1.00 month"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2023-02-01', '2023-02-28'),
            1.00,
            "Full February (non-leap) 2023/02/01 → 2023/02/28 → 1.00 month"
        );

        // Multiple full months
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-01-01', '2024-03-31'),
            3.00,
            "3 full months 2024/01/01 → 2024/03/31 → 3.00 months"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-01-01', '2024-06-30'),
            6.00,
            "6 full months 2024/01/01 → 2024/06/30 → 6.00 months"
        );

        // Partial month at start
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-01-15', '2024-01-31'),
            0.57,
            "Partial from mid-month 2024/01/15 → 2024/01/31 (17 days) → 0.57 months"
        );

        // Partial month at end
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-01-01', '2024-02-15'),
            1.50,
            "Full Jan + 15 days Feb → 2024/01/01 → 2024/02/15 → 1.50 months"
        );

        // Cross-year period
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2023-11-01', '2024-02-29'),
            4.00,
            "Cross-year 2023/11/01 → 2024/02/29 → 4.00 months"
        );

        // Long period (multiple years)
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2015-04-01', '2025-03-31'),
            120.00,
            "10 fiscal years 2015/04/01 → 2025/03/31 → 120.00 months"
        );

        // Mixed partial periods
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-01-10', '2024-03-20'),
            2.37,
            "Partial start/end 2024/01/10 → 2024/03/20 → 2.37 months"
        );

        // Edge case: End of month boundaries
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal('2024-01-31', '2024-02-29'),
            1.00,
            "End-to-end of months 2024/01/31 → 2024/02/29 → 1.00 month (30 days)"
        );

        // Carbon input
        $this->assertResult(
            $this->dateService->calculateMonthsDecimal(
                Carbon::parse('2024-04-01'),
                Carbon::parse('2024-04-30')
            ),
            1.00,
            "Carbon objects input → 1.00 month"
        );
    }

    // ========================================================================
    // TEST: calculateMonthsFloor()
    // ========================================================================
    private function testCalculateMonthsFloor(): void
    {
        $this->printSectionHeader('calculateMonthsFloor');
        $this->line("  Tính số tháng làm tròn xuống (floor)\n");

        $this->assertResult(
            $this->dateService->calculateMonthsFloor(null, null),
            0,
            "NULL inputs → 0"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsFloor('2024-01-01', '2024-01-15'),
            0,
            "15 days → floor(0.50) = 0"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsFloor('2024-01-01', '2024-02-15'),
            1,
            "1 month + 15 days → floor(1.50) = 1"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsFloor('2015-04-01', '2016-03-31'),
            12,
            "Full fiscal year → floor(12.00) = 12"
        );

        $this->assertResult(
            $this->dateService->calculateMonthsFloor('2015-01-23', '2015-03-31'),
            2,
            "2.27 months → floor(2.27) = 2"
        );
    }

    // ========================================================================
    // TEST: calculateCalendarMonths()
    // ========================================================================
    private function testCalculateCalendarMonths(): void
    {
        $this->printSectionHeader('calculateCalendarMonths');
        $this->line("  Đếm số tháng lịch (calendar months touched)\n");

        $this->assertResult(
            $this->dateService->calculateCalendarMonths(null, null),
            0,
            "NULL inputs → 0"
        );

        $this->assertResult(
            $this->dateService->calculateCalendarMonths('2024-03-31', '2024-01-01'),
            0,
            "End before start → 0"
        );

        $this->assertResult(
            $this->dateService->calculateCalendarMonths('2024-01-15', '2024-01-15'),
            1,
            "Same day → 1 month"
        );

        $this->assertResult(
            $this->dateService->calculateCalendarMonths('2015-04-01', '2016-03-31'),
            12,
            "Full fiscal year 04/01 → 03/31 → 12 months"
        );

        $this->assertResult(
            $this->dateService->calculateCalendarMonths('2015-01-23', '2015-03-31'),
            3,
            "2015/01/23 → 2015/03/31 → 3 months (Jan, Feb, Mar)"
        );

        $this->assertResult(
            $this->dateService->calculateCalendarMonths('2024-01-01', '2024-01-31'),
            1,
            "Full January → 1 month"
        );

        $this->assertResult(
            $this->dateService->calculateCalendarMonths('2024-01-15', '2024-03-15'),
            3,
            "Mid Jan to mid Mar (same day) → 3 months"
        );

        $this->assertResult(
            $this->dateService->calculateCalendarMonths('2024-01-15', '2024-03-10'),
            2,
            "Mid Jan to early Mar (end day < start day) → 2 months"
        );
    }

    // ========================================================================
    // TEST: calculateDaysInclusive()
    // ========================================================================
    private function testCalculateDaysInclusive(): void
    {
        $this->printSectionHeader('calculateDaysInclusive');
        $this->line("  Tính số ngày bao gồm cả ngày đầu và cuối\n");

        $this->assertResult(
            $this->dateService->calculateDaysInclusive(null, null),
            0,
            "NULL inputs → 0"
        );

        $this->assertResult(
            $this->dateService->calculateDaysInclusive('2024-01-31', '2024-01-01'),
            0,
            "End before start → 0"
        );

        $this->assertResult(
            $this->dateService->calculateDaysInclusive('2024-01-15', '2024-01-15'),
            1,
            "Same day → 1 day"
        );

        $this->assertResult(
            $this->dateService->calculateDaysInclusive('2024-01-01', '2024-01-03'),
            3,
            "Jan 1-3 → 3 days (1st, 2nd, 3rd)"
        );

        $this->assertResult(
            $this->dateService->calculateDaysInclusive('2024-01-01', '2024-01-31'),
            31,
            "Full January → 31 days"
        );

        $this->assertResult(
            $this->dateService->calculateDaysInclusive('2024-02-01', '2024-02-29'),
            29,
            "February 2024 (leap year) → 29 days"
        );

        $this->assertResult(
            $this->dateService->calculateDaysInclusive('2023-02-01', '2023-02-28'),
            28,
            "February 2023 (non-leap) → 28 days"
        );

        $this->assertResult(
            $this->dateService->calculateDaysInclusive('2015-04-01', '2016-03-31'),
            366,
            "Full fiscal year 2015 → 366 days (includes Feb 2016 leap)"
        );

        $this->assertResult(
            $this->dateService->calculateDaysInclusive('2016-04-01', '2016-04-19'),
            19,
            "April 1-19, 2016 → 19 days"
        );

        $this->assertResult(
            $this->dateService->calculateDaysInclusive('2024-12-25', '2025-01-05'),
            12,
            "Cross-year Dec 25 → Jan 5 → 12 days"
        );
    }

    // ========================================================================
    // TEST: calculateDaysAsMonths()
    // ========================================================================
    private function testCalculateDaysAsMonths(): void
    {
        $this->printSectionHeader('calculateDaysAsMonths');
        $this->line("  Chuyển đổi số ngày sang tháng thập phân (30 days = 1 month)\n");

        $this->assertResult(
            $this->dateService->calculateDaysAsMonths(null, null),
            0.0,
            "NULL inputs → 0.0"
        );

        $this->assertResult(
            $this->dateService->calculateDaysAsMonths('2024-01-01', '2024-01-30'),
            1.00,
            "30 days → 1.00 month"
        );

        $this->assertResult(
            $this->dateService->calculateDaysAsMonths('2024-01-01', '2024-01-15'),
            0.50,
            "15 days → 0.50 month"
        );

        $this->assertResult(
            $this->dateService->calculateDaysAsMonths('2024-01-01', '2024-01-01'),
            0.03,
            "1 day → 0.03 month"
        );

        $this->assertResult(
            $this->dateService->calculateDaysAsMonths('2024-01-01', '2024-02-29'),
            2.00,
            "60 days (Jan 31 + Feb 29) → 2.00 months"
        );
    }

    // ========================================================================
    // TEST: calculateWorkingYearsDecimal()
    // ========================================================================
    private function testCalculateWorkingYearsDecimal(): void
    {
        $this->printSectionHeader('calculateWorkingYearsDecimal');
        $this->line("  Tính số năm làm việc dạng thập phân\n");

        $this->assertResult(
            $this->dateService->calculateWorkingYearsDecimal(null, null),
            0.0,
            "NULL inputs → 0.0"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingYearsDecimal('2015-04-01', '2016-03-31'),
            1.0,
            "12 months → 1.0 year"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingYearsDecimal('2015-04-01', '2015-09-30'),
            0.5,
            "6 months → 0.5 year"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingYearsDecimal('2015-04-01', '2025-03-31'),
            10.0,
            "10 fiscal years → 10.0 years"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingYearsDecimal('2020-01-01', '2020-03-31'),
            0.3,
            "3 months → 0.3 year (rounded to 1 decimal)"
        );
    }

    // ========================================================================
    // TEST: calculateWorkingMonths()
    // ========================================================================
    private function testCalculateWorkingMonths(): void
    {
        $this->printSectionHeader('calculateWorkingMonths');
        $this->line("  Tính tổng số tháng làm việc (calendar months)\n");

        $this->assertResult(
            $this->dateService->calculateWorkingMonths(null, null),
            0,
            "NULL inputs → 0"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingMonths('2015-04-01', '2016-03-31'),
            12,
            "Full fiscal year → 12 months"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingMonths('2015-04-01', '2025-03-31'),
            120,
            "10 fiscal years → 120 months"
        );
    }

    // ========================================================================
    // TEST: calculateWorkingPeriodFormatted()
    // ========================================================================
    private function testCalculateWorkingPeriodFormatted(): void
    {
        $this->printSectionHeader('calculateWorkingPeriodFormatted');
        $this->line("  Format khoảng thời gian làm việc theo định dạng Nhật Bản (X年Yヶ月)\n");

        $this->assertResult(
            $this->dateService->calculateWorkingPeriodFormatted(null, null),
            '0年0ヶ月',
            "NULL inputs → 0年0ヶ月"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingPeriodFormatted('2015-04-01', '2016-03-31'),
            '1年0ヶ月',
            "12 months → 1年0ヶ月"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingPeriodFormatted('2015-04-01', '2016-09-30'),
            '1年6ヶ月',
            "18 months → 1年6ヶ月"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingPeriodFormatted('2015-04-01', '2025-03-31'),
            '10年0ヶ月',
            "120 months → 10年0ヶ月"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingPeriodFormatted('2015-04-01', '2025-08-31'),
            '10年5ヶ月',
            "125 months → 10年5ヶ月"
        );

        $this->assertResult(
            $this->dateService->calculateWorkingPeriodFormatted('2024-01-15', '2024-03-20'),
            '0年3ヶ月',
            "3 calendar months → 0年3ヶ月"
        );
    }

    // ========================================================================
    // TEST: formatYearsMonths()
    // ========================================================================
    private function testFormatYearsMonths(): void
    {
        $this->printSectionHeader('formatYearsMonths');
        $this->line("  Format số tháng thành chuỗi X年Yヶ月\n");

        $this->assertResult(
            $this->dateService->formatYearsMonths(0),
            '0年0ヶ月',
            "0 months → 0年0ヶ月"
        );

        $this->assertResult(
            $this->dateService->formatYearsMonths(-5),
            '0年0ヶ月',
            "Negative value → 0年0ヶ月"
        );

        $this->assertResult(
            $this->dateService->formatYearsMonths(1),
            '0年1ヶ月',
            "1 month → 0年1ヶ月"
        );

        $this->assertResult(
            $this->dateService->formatYearsMonths(11),
            '0年11ヶ月',
            "11 months → 0年11ヶ月"
        );

        $this->assertResult(
            $this->dateService->formatYearsMonths(12),
            '1年0ヶ月',
            "12 months → 1年0ヶ月"
        );

        $this->assertResult(
            $this->dateService->formatYearsMonths(13),
            '1年1ヶ月',
            "13 months → 1年1ヶ月"
        );

        $this->assertResult(
            $this->dateService->formatYearsMonths(125),
            '10年5ヶ月',
            "125 months → 10年5ヶ月"
        );

        $this->assertResult(
            $this->dateService->formatYearsMonths(12.7),
            '1年0ヶ月',
            "12.7 (float) → floor = 1年0ヶ月"
        );
    }

    // ========================================================================
    // TEST: convertMonthsToYears()
    // ========================================================================
    private function testConvertMonthsToYears(): void
    {
        $this->printSectionHeader('convertMonthsToYears');
        $this->line("  Chuyển đổi số tháng sang số năm thập phân\n");

        $this->assertResult(
            $this->dateService->convertMonthsToYears(0),
            0.0,
            "0 months → 0.0 years"
        );

        $this->assertResult(
            $this->dateService->convertMonthsToYears(6),
            0.5,
            "6 months → 0.5 year"
        );

        $this->assertResult(
            $this->dateService->convertMonthsToYears(12),
            1.0,
            "12 months → 1.0 year"
        );

        $this->assertResult(
            $this->dateService->convertMonthsToYears(18),
            1.5,
            "18 months → 1.5 years"
        );

        $this->assertResult(
            $this->dateService->convertMonthsToYears(125),
            10.4,
            "125 months → 10.4 years (rounded to 1 decimal)"
        );

        $this->assertResult(
            $this->dateService->convertMonthsToYears(7),
            0.6,
            "7 months → 0.6 year (7/12 = 0.583... → 0.6)"
        );
    }

    // ========================================================================
    // TEST: floorToDecimal()
    // ========================================================================
    private function testFloorToDecimal(): void
    {
        $this->printSectionHeader('floorToDecimal');
        $this->line("  Làm tròn xuống đến N chữ số thập phân (有利な方向に切り捨て)\n");

        // User's specific examples for Affect Months
        $this->assertResult(
            $this->dateService->floorToDecimal(0.63, 1),
            0.6,
            "0.63 → 0.6 (19 days leave)"
        );

        $this->assertResult(
            $this->dateService->floorToDecimal(2.27, 1),
            2.2,
            "2.27 → 2.2 (2 months + 8 days)"
        );

        $this->assertResult(
            $this->dateService->floorToDecimal(12.00, 1),
            12.0,
            "12.00 → 12.0 (full year)"
        );

        $this->assertResult(
            $this->dateService->floorToDecimal(14.90, 1),
            14.9,
            "14.90 → 14.9 (total affect)"
        );

        // Edge cases
        $this->assertResult(
            $this->dateService->floorToDecimal(0.09, 1),
            0.0,
            "0.09 → 0.0 (less than 0.1)"
        );

        $this->assertResult(
            $this->dateService->floorToDecimal(0.99, 1),
            0.9,
            "0.99 → 0.9 (just under 1)"
        );

        $this->assertResult(
            $this->dateService->floorToDecimal(1.0, 1),
            1.0,
            "1.0 → 1.0 (exact value)"
        );

        // 2 decimal places
        $this->assertResult(
            $this->dateService->floorToDecimal(2.279, 2),
            2.27,
            "2.279 → 2.27 (2 decimals)"
        );

        $this->assertResult(
            $this->dateService->floorToDecimal(0.639, 2),
            0.63,
            "0.639 → 0.63 (2 decimals)"
        );
    }

    // ========================================================================
    // TEST: getOverlappingPeriod()
    // ========================================================================
    private function testGetOverlappingPeriod(): void
    {
        $this->printSectionHeader('getOverlappingPeriod');
        $this->line("  Tìm khoảng thời gian trùng lặp giữa 2 periods\n");

        // No overlap - check period completely before range
        $result = $this->dateService->getOverlappingPeriod(
            '2024-01-01', '2024-01-31',  // check period
            '2024-03-01', '2024-03-31'   // reference range
        );
        $this->assertResult(
            $result,
            null,
            "Check period (Jan) before range (Mar) → null"
        );

        // No overlap - check period completely after range
        $result = $this->dateService->getOverlappingPeriod(
            '2024-05-01', '2024-05-31',  // check period
            '2024-03-01', '2024-03-31'   // reference range
        );
        $this->assertResult(
            $result,
            null,
            "Check period (May) after range (Mar) → null"
        );

        // Full overlap - check period inside range
        $result = $this->dateService->getOverlappingPeriod(
            '2024-02-10', '2024-02-20',  // check period
            '2024-02-01', '2024-02-29'   // reference range
        );
        $this->line("  ✅ Check period inside range → overlap = check period");
        $this->line("     → Start: " . ($result ? $result['start']->format('Y-m-d') : 'null'));
        $this->line("     → End: " . ($result ? $result['end']->format('Y-m-d') : 'null'));
        if ($result && $result['start']->format('Y-m-d') === '2024-02-10' && $result['end']->format('Y-m-d') === '2024-02-20') {
            $this->passCount++;
        } else {
            $this->failCount++;
        }

        // Partial overlap - check period starts before range
        $result = $this->dateService->getOverlappingPeriod(
            '2024-01-15', '2024-02-15',  // check period
            '2024-02-01', '2024-02-29'   // reference range
        );
        $this->line("  ✅ Check starts before range → overlap = range start to check end");
        $this->line("     → Start: " . ($result ? $result['start']->format('Y-m-d') : 'null'));
        $this->line("     → End: " . ($result ? $result['end']->format('Y-m-d') : 'null'));
        if ($result && $result['start']->format('Y-m-d') === '2024-02-01' && $result['end']->format('Y-m-d') === '2024-02-15') {
            $this->passCount++;
        } else {
            $this->failCount++;
        }

        // Partial overlap - check period ends after range
        $result = $this->dateService->getOverlappingPeriod(
            '2024-02-15', '2024-03-15',  // check period
            '2024-02-01', '2024-02-29'   // reference range
        );
        $this->line("  ✅ Check ends after range → overlap = check start to range end");
        $this->line("     → Start: " . ($result ? $result['start']->format('Y-m-d') : 'null'));
        $this->line("     → End: " . ($result ? $result['end']->format('Y-m-d') : 'null'));
        if ($result && $result['start']->format('Y-m-d') === '2024-02-15' && $result['end']->format('Y-m-d') === '2024-02-29') {
            $this->passCount++;
        } else {
            $this->failCount++;
        }

        // Check period contains range
        $result = $this->dateService->getOverlappingPeriod(
            '2024-01-01', '2024-03-31',  // check period
            '2024-02-01', '2024-02-29'   // reference range
        );
        $this->line("  ✅ Check period contains range → overlap = entire range");
        $this->line("     → Start: " . ($result ? $result['start']->format('Y-m-d') : 'null'));
        $this->line("     → End: " . ($result ? $result['end']->format('Y-m-d') : 'null'));
        if ($result && $result['start']->format('Y-m-d') === '2024-02-01' && $result['end']->format('Y-m-d') === '2024-02-29') {
            $this->passCount++;
        } else {
            $this->failCount++;
        }

        // Edge case - exactly touching (same day boundary)
        $result = $this->dateService->getOverlappingPeriod(
            '2024-01-31', '2024-02-15',  // check period
            '2024-01-01', '2024-01-31'   // reference range
        );
        $this->line("  ✅ Touching at boundary (Jan 31) → overlap = 1 day");
        $this->line("     → Start: " . ($result ? $result['start']->format('Y-m-d') : 'null'));
        $this->line("     → End: " . ($result ? $result['end']->format('Y-m-d') : 'null'));
        if ($result && $result['start']->format('Y-m-d') === '2024-01-31' && $result['end']->format('Y-m-d') === '2024-01-31') {
            $this->passCount++;
        } else {
            $this->failCount++;
        }
    }

    // ========================================================================
    // TEST: getFiscalYear()
    // ========================================================================
    private function testGetFiscalYear(): void
    {
        $this->printSectionHeader('getFiscalYear');
        $this->line("  Lấy năm tài chính Nhật Bản (April 1 - March 31)\n");

        $this->assertResult(
            $this->dateService->getFiscalYear('2024-04-01'),
            2024,
            "April 1, 2024 → FY 2024"
        );

        $this->assertResult(
            $this->dateService->getFiscalYear('2024-03-31'),
            2023,
            "March 31, 2024 → FY 2023"
        );

        $this->assertResult(
            $this->dateService->getFiscalYear('2024-01-15'),
            2023,
            "January 15, 2024 → FY 2023"
        );

        $this->assertResult(
            $this->dateService->getFiscalYear('2024-12-31'),
            2024,
            "December 31, 2024 → FY 2024"
        );

        $this->assertResult(
            $this->dateService->getFiscalYear('2025-03-01'),
            2024,
            "March 1, 2025 → FY 2024"
        );

        $this->assertResult(
            $this->dateService->getFiscalYear('2025-04-01'),
            2025,
            "April 1, 2025 → FY 2025"
        );

        // Carbon input
        $this->assertResult(
            $this->dateService->getFiscalYear(Carbon::parse('2024-06-15')),
            2024,
            "Carbon: June 15, 2024 → FY 2024"
        );
    }

    // ========================================================================
    // TEST: getFiscalYearStart()
    // ========================================================================
    private function testGetFiscalYearStart(): void
    {
        $this->printSectionHeader('getFiscalYearStart');
        $this->line("  Lấy ngày bắt đầu năm tài chính (April 1)\n");

        $result = $this->dateService->getFiscalYearStart(2024);
        $this->assertResult(
            $result->format('Y-m-d'),
            '2024-04-01',
            "FY 2024 start → 2024-04-01"
        );

        $result = $this->dateService->getFiscalYearStart(2023);
        $this->assertResult(
            $result->format('Y-m-d'),
            '2023-04-01',
            "FY 2023 start → 2023-04-01"
        );

        $result = $this->dateService->getFiscalYearStart(2020);
        $this->assertResult(
            $result->format('Y-m-d'),
            '2020-04-01',
            "FY 2020 start → 2020-04-01"
        );
    }

    // ========================================================================
    // TEST: getFiscalYearEnd()
    // ========================================================================
    private function testGetFiscalYearEnd(): void
    {
        $this->printSectionHeader('getFiscalYearEnd');
        $this->line("  Lấy ngày kết thúc năm tài chính (March 31 of next year)\n");

        $result = $this->dateService->getFiscalYearEnd(2024);
        $this->assertResult(
            $result->format('Y-m-d'),
            '2025-03-31',
            "FY 2024 end → 2025-03-31"
        );

        $result = $this->dateService->getFiscalYearEnd(2023);
        $this->assertResult(
            $result->format('Y-m-d'),
            '2024-03-31',
            "FY 2023 end → 2024-03-31"
        );

        $result = $this->dateService->getFiscalYearEnd(2019);
        $this->assertResult(
            $result->format('Y-m-d'),
            '2020-03-31',
            "FY 2019 end → 2020-03-31 (leap year boundary)"
        );
    }

    // ========================================================================
    // SUMMARY
    // ========================================================================
    private function printSummary(): void
    {
        $total = $this->passCount + $this->failCount;
        $percentage = $total > 0 ? round(($this->passCount / $total) * 100, 1) : 0;

        $this->info("\n" . str_repeat('=', 80));
        $this->info("                              TEST SUMMARY");
        $this->info(str_repeat('=', 80));

        $this->line("");
        $this->line("  Total Tests:  {$total}");
        $this->line("  ✅ Passed:    {$this->passCount}");

        if ($this->failCount > 0) {
            $this->error("  ❌ Failed:    {$this->failCount}");
        } else {
            $this->line("  ❌ Failed:    {$this->failCount}");
        }

        $this->line("  Success Rate: {$percentage}%");
        $this->line("");

        if ($this->failCount === 0) {
            $this->info("  🎉 ALL TESTS PASSED! DateService is working correctly.");
        } else {
            $this->error("  ⚠️  Some tests failed. Please review the results above.");
        }

        $this->info(str_repeat('=', 80) . "\n");
    }
}
