<?php

namespace App\Helpers;

use Carbon\Carbon;

class DateHelper
{
    /**
     * Return a date according to the timezone of the user, in a
     * short format like "Oct 29, 1981".
     *
     * @param Carbon $date
     * @param string $timezone
     * @return string
     */
    public static function formatDate(Carbon $date, string $timezone = null): string
    {
        if ($timezone) {
            $date->setTimezone($timezone);
        }

        return $date->isoFormat(trans('format.date'));
    }

    /**
     * Return a date and the time according to the timezone of the user, in a
     * short format like "Oct 29, 1981 19:32".
     *
     * @param Carbon $date
     * @param string $timezone
     * @return string
     */
    public static function formatShortDateWithTime(Carbon $date, string $timezone = null): string
    {
        if ($timezone) {
            $date->setTimezone($timezone);
        }

        return $date->isoFormat(trans('format.short_date_year_time'));
    }

    /**
     * Return the day and the month in a format like "July 29th".
     *
     * @param Carbon $date
     * @return string
     */
    public static function formatMonthAndDay(Carbon $date): string
    {
        return $date->isoFormat(trans('format.long_month_day'));
    }

    /**
     * Return the short month and the year in a format like "Jul 2020".
     *
     * @param Carbon $date
     * @return string
     */
    public static function formatMonthAndYear(Carbon $date): string
    {
        return $date->isoFormat(trans('format.short_month_day'));
    }

    /**
     * Return the day and the month in a format like "Jul 29".
     *
     * @param Carbon $date
     * @return string
     */
    public static function formatShortMonthAndDay(Carbon $date): string
    {
        return $date->isoFormat(trans('format.short_date'));
    }

    /**
     * Return the day and the month in a format like "Monday (July 29th)".
     *
     * @param Carbon $date
     * @param string $timezone
     * @return string
     */
    public static function formatDayAndMonthInParenthesis(Carbon $date, string $timezone = null): string
    {
        if ($timezone) {
            $date->setTimezone($timezone);
        }

        return $date->isoFormat(trans('format.day_month_parenthesis'));
    }

    /**
     * Return the complete date like "Monday, July 29th 2020".
     *
     * @param Carbon $date
     * @return string
     */
    public static function formatFullDate(Carbon $date): string
    {
        return $date->isoFormat(trans('format.full_date'));
    }

    /**
     * Translate the given month to a string using the locale of the app.
     *
     * @param Carbon $date
     * @return string
     */
    public static function translateMonth(Carbon $date): string
    {
        return $date->isoFormat(trans('format.full_month'));
    }

    /**
     * Return the day as a string like "Wednesday".
     *
     * @param Carbon $date
     * @return string
     */
    public static function day(Carbon $date): string
    {
        return $date->isoFormat(trans('format.day'));
    }

    /**
     * Return the day as a string like "Jul. 29th".
     *
     * @param Carbon $date
     * @return string
     */
    public static function dayWithShortMonth(Carbon $date): string
    {
        return $date->isoFormat(trans('format.day_short_month'));
    }

    /**
     * Calculate the next occurence in the future for this date.
     *
     * @param Carbon $date
     * @return Carbon
     */
    public static function getNextOccurence(Carbon $date): Carbon
    {
        if ($date->isFuture()) {
            return $date;
        }

        $date->addYear();

        while ($date->isPast()) {
            $date = static::getNextOccurence($date);
        }

        return $date;
    }

    /**
     * Get the number of days in a given year.
     *
     * @param Carbon $date
     * @return int
     */
    public static function getNumberOfDaysInYear(Carbon $date): int
    {
        return $date->isLeapYear() ? 366 : 365;
    }

    /**
     * Determine if the date is in the future, in the present or in the past.
     *
     * @param Carbon $date
     * @return string
     */
    public static function determineDateStatus(Carbon $date): string
    {
        $status = '';
        if ($date->isFuture()) {
            $status = 'future';
        } else {
            if ($date->isCurrentDay()) {
                $status = 'current';
            } else {
                $status = 'past';
            }
        }

        return $status;
    }

    /**
     * Return a string indicating the number of days or hours left, like
     * `3 hours left` or `1 day left`, depending on the given date.
     *
     * @param Carbon $date
     * @return string
     */
    public static function hoursOrDaysLeft(Carbon $date): string
    {
        $now = Carbon::now();
        $hoursLeft = $now->diffInHours($date);

        if ($hoursLeft < 24) {
            $timeLeft = trans_choice('app.hours_left', $hoursLeft);
        } else {
            $timeLeft = trans_choice('app.days_left', $now->diffInDays($date));
        }

        return $timeLeft;
    }
}
