<?php
declare(strict_types=1);

namespace App\Helpers;

use Carbon\Exceptions\InvalidDateException;
use Exception;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;

class DateHelper
{
    const DB_FORMAT = 'Y-MM-DD';
    const HUMAN_TEXT_FORMAT = 'D MMMM Y';
    const HUMAN_DATE_FORMAT = 'DD.MM.Y';
    const MINIMAL_RANDOM_YEAR = 1970;
    const SECONDS_IN_YEAR = 365 * 24 * 60 * 60;

    const YEARS = 'год|года|лет';
    const MONTHS = 'месяц|месяца|месяцев';
    const DAYS = 'день|дня|дней';

    /**
     * @param string $date
     * @param bool $monthAsNumber
     * @return string
     */
    public static function getHumanDate(string $date, bool $monthAsNumber = false): string
    {
        $format = ($monthAsNumber) ? self::HUMAN_DATE_FORMAT : self::HUMAN_TEXT_FORMAT;
        $dt = Carbon::parse($date);
        return Str::lower($dt->isoFormat($format));
    }

    /**
     * Случайная дата за последние X лет в формате YYYY-MM-DD
     * @param int|null $last_years
     * @return string
     */
    public static function getRandomDate(?int $last_years = 7): string
    {
        if (($last_years > ((int)date('Y') - self::MINIMAL_RANDOM_YEAR)) || ($last_years < 0)) {
            throw new InvalidDateException('last_years', $last_years, 1);
        }
        $seconds = rand(0, $last_years * self::SECONDS_IN_YEAR); // случайное число секунд в диапазоне от 0 до Х лет
        return Carbon::createFromTimestamp(strtotime('now') - $seconds)->isoFormat(self::DB_FORMAT);
    }

    /**
     * @param string $date
     * @return string
     */
    public static function getDateForDB(string $date): string
    {
        return Carbon::parse($date)->isoFormat(self::DB_FORMAT);
    }

    /**
     * @param string $date
     * @param int $months
     * @return string
     */
    public static function addMonths(string $date, int $months): string
    {
        return Carbon::parse($date)->addMonths($months)->isoFormat(self::DB_FORMAT);
    }

    /**
     * @param string $string
     * @return bool
     */
    public static function isDate(string $string): bool
    {
        if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$string)) {
            return true;
        } else {
            return false;
        }
    }

}
