<?php

namespace App\Helpers\Support;

use Carbon\Carbon;

class PeriodRangeDefiner
{
    /**
     * @param  string       $period   'daily' | 'weekly' | 'fortnightly' | 'monthly' | 'quarterly' | 'four_monthly' | 'yearly' ...
     * @param  Carbon|null  $reference_date Reference Date (default: Now)
     * @return [Carbon $start, Carbon $end] Period limits based on the $reference_date
     */

    public static function range(string $period, ?Carbon $reference_date = null): array
    {
        // Define ReferenceDate with TimeZone
        $tz = config('app.timezone');
        $now = ($reference_date ?? Carbon::now($tz))->clone()->timezone($tz);

        // Normaliza el inicio/fin del día siempre con el mismo TZ
        $start = $now->clone();
        $end   = $now->clone();

        // Calculate Period Limits for Frequency
        switch (strtolower($period)) {
            case 'daily': // Diario
                $start = $now->clone()->startOfDay();
                $end   = $now->clone()->endOfDay();
                break;

            case 'weekly': // Semanal
                // ISO Week starting on MONDAY
                $start = $now->clone()->startOfWeek(Carbon::MONDAY)->startOfDay();
                $end   = $now->clone()->endOfWeek(Carbon::MONDAY)->endOfDay();
                break;

            case 'fortnightly': // Quincenal (según mes actual: 1–15 y 16–fin)
                if ($now->day <= 15) {
                    $start = $now->clone()->startOfMonth()->startOfDay();
                    $end   = $now->clone()->startOfMonth()->day(15)->endOfDay();
                } else {
                    $start = $now->clone()->startOfMonth()->day(16)->startOfDay();
                    $end   = $now->clone()->endOfMonth()->endOfDay();
                }
                break;

            case 'monthly': // Mensual
            default: // Mensual por Defecto
                $start = $now->clone()->startOfMonth()->startOfDay();
                $end   = $now->clone()->endOfMonth()->endOfDay();
                break;

            case 'quarterly': // Trimestral Fijo (Ene–Mar, Abr-Jun, Jul-Sep, Oct-Dic)
                $month = (int) $now->format('n'); // Current Month

                if ($month >= 1 && $month <= 3) {
                    // Ene–Mar
                    $start = $now->clone()->month(1)->startOfMonth()->startOfDay();
                    $end   = $now->clone()->month(3)->endOfMonth()->endOfDay();
                } elseif ($month >= 4 && $month <= 6) {
                    // Abr-Jun
                    $start = $now->clone()->month(4)->startOfMonth()->startOfDay();
                    $end   = $now->clone()->month(6)->endOfMonth()->endOfDay();
                } elseif ($month >= 7 && $month <= 9) {
                    // Jul-Sep
                    $start = $now->clone()->month(7)->startOfMonth()->startOfDay();
                    $end   = $now->clone()->month(9)->endOfMonth()->endOfDay();
                } else {
                    // Oct-Dic
                    $start = $now->clone()->month(10)->startOfMonth()->startOfDay();
                    $end   = $now->clone()->month(12)->endOfMonth()->endOfDay();
                }
                break;

            case 'four_monthly': // Cuatrimestral Fijo (Ene–Abr, May–Ago, Sep–Dic)
                $month = (int) $now->format('n'); // Current Month

                if ($month >= 1 && $month <= 4) {
                    // Ene–Abr
                    $start = $now->clone()->month(1)->startOfMonth()->startOfDay();
                    $end   = $now->clone()->month(4)->endOfMonth()->endOfDay();
                } elseif ($month >= 5 && $month <= 8) {
                    // May–Ago
                    $start = $now->clone()->month(5)->startOfMonth()->startOfDay();
                    $end   = $now->clone()->month(8)->endOfMonth()->endOfDay();
                } else {
                    // Sep–Dic
                    $start = $now->clone()->month(9)->startOfMonth()->startOfDay();
                    $end   = $now->clone()->month(12)->endOfMonth()->endOfDay();
                }
                break;

            case 'yearly': // Anual
                $start = $now->clone()->startOfYear()->startOfDay();
                $end   = $now->clone()->endOfYear()->endOfDay();
                break;
        }

        // Return Period Limits calculated
        return [$start, $end];
    }
}
