<?php

namespace App\Repositories\Core;

use Carbon\Carbon;
use League\Period\Period;
use League\Period\Duration;
use League\Period\Sequence;
use League\Period\Chart\Dataset;
use function League\Period\duration;
use function League\Period\interval_after;

class DateRange
{
    public static function getPeriodsLastMonthWithLabels($nb, $with_actual = true)
    {
        $periods = DateRange::PeriodsToCarbon(DateRange::getPeriodsLastMonth($nb, $with_actual));
        $labels = DateRange::getMonthNames($periods);
        foreach ($labels as $label) {
            $data[$label] = $periods;
        }
        return $data;
    }

    public static function getAllMonthNames()
    {
        return self::getMonthNames(self::PeriodsToCarbon(self::getPeriodsLastMonth(12)));
    }

    public static function getPeriodsLastMonth($nb = 1, $with_actual = true)
    {
        $end = $with_actual ? Carbon::now()->endOfMonth() : self::lastMonth();
        $begin = ($nb == 1) ? $end->copy()->startOfMonth() : $end->copy()->startOfMonth()->subMonth($nb-1);
        $t = self::getPeriodsbyMonth($begin, $end);
        return self::getPeriodsbyMonth($begin, $end);
    }

    public static function getMonthNamesByPeriods($periods)
    {
        $months = [];
        foreach ($periods as $period) {
            $date = self::DatePointToCarbon($period->getStartDate());
            $months[] = DateTime::getMonthName($date);
        }
        return $months;
    }

    public static function getMonthNames($periods)
    {
        $months = [];
        foreach ($periods as $period) {
            $months[] = DateTime::getMonthName($period['start']);
        }
        return $months;
    }

    public static function getPeriodsLastWeek($nb = 1, $with_actual = true)
    {
        $end = $with_actual ? Carbon::now()->endOfWeek() : self::lastWeek();
        $begin = $end->copy()->subWeek($nb);
        return static::getPeriodsbyWeek($begin, $end);
    }

    public static function getPeriodsLastDay($nb = 1, $with_actual = true)
    {
        $end = $with_actual ? Carbon::now()->endOfDay() : static::lastDay();
        $begin = $end->copy()->subDay($nb);
        return static::getPeriodsbyDay($begin, $end);
    }

    public static function byDay()
    {
        return [Carbon::now()->startOfDay(), Carbon::now()->endOfDay()];
    }

    public static function byWeek()
    {
        return [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()];
    }

    public static function byMonth()
    {
        return [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()];
    }

    public static function byQuarter()
    {
        return [Carbon::now()->startOfQuarter(), Carbon::now()->endOfQuarter()];
    }

    public static function bySemester()
    {
        $quarter = Carbon::now()->quarter;
        switch ($quarter) {
        case 1:
        case 2:
            $date = Carbon::now()->startOfYear();
            break;
        case 3:
            $date = Carbon::now()->startOfQuarter();
            break;
        case 4:
            $date = Carbon::now()->subMonth(3)->startOfQuarter();
            break;
        }
        return [$date, $date->addMonth(6)];
    }

    public static function byYear()
    {
        return [Carbon::now()->startOfYear(), Carbon::now()->endOfYear()];
    }

    public static function lastMonth()
    {
        return Carbon::now()->subMonth()->startOfMonth();
    }

    public static function lastWeek()
    {
        return Carbon::now()->subWeek()->startOfWeek();
    }

    public static function lastDay()
    {
        return Carbon::now()->subDay()->startOfDay();
    }

    public static function getPeriodsbyMonth($begin, $end, $interval = 1)
    {
        return self::getPeriods($begin, $end, "$interval MONTH");
    }

    public static function getPeriodsbyWeek($begin, $end, $interval = 1)
    {
        return self::getPeriods($begin, $end, "$interval WEEK");
    }

    public static function getPeriodsbyDay($begin, $end, $interval = 1)
    {
        return self::getPeriods($begin, $end, "$interval DAY");
    }

    public static function getPeriods($begin, $end, $duration, $interval = 1)
    {
        $period = new Period($begin, $end);
        foreach ($period->getDatePeriod($duration) as $day) {
            $daterange[] = interval_after($day, $duration);
        }
        return $daterange;
    }

    public static function PeriodsToCarbon($periods)
    {
        $data = [];
        foreach ($periods as $period) {
            $data[] = self::PeriodToCarbon($period);
        }
        return $data;
    }

    public static function PeriodToCarbon($period)
    {
        return ['start' => self::DatePointToCarbon($period->getStartDate()), 'end' => self::DatePointToCarbon($period->getEndDate())];
    }

    public static function DatePointToCarbon($date)
    {
        return Carbon::createFromFormat('Y-m-d H:i:s', $date->format('Y-m-d H:i:s'));
    }
}
