<?php

/**
 * This file is part of the Carbon package.
 *
 * (c) Brian Nesbitt <brian@nesbot.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace Carbon\Traits;

/**
 * Trait Week.
 *
 * week and ISO week number, year and count in year.
 *
 * Depends on the following properties:
 *
 * @property int $daysInYear
 * @property int $dayOfWeek
 * @property int $dayOfYear
 * @property int $year
 *
 * Depends on the following methods:
 *
 * @method static addWeeks(int $weeks = 1)
 * @method static copy()
 * @method static dayOfYear(int $dayOfYear)
 * @method string getTranslationMessage(string $key, ?string $locale = null, ?string $default = null, $translator = null)
 * @method static next(int|string $day = null)
 * @method static startOfWeek(int $day = 1)
 * @method static subWeeks(int $weeks = 1)
 * @method static year(int $year = null)
 */
trait Week
{
    /**
     * Set/get the week number of year using given first day of week and first
     * day of year included in the first week. Or use ISO format if no settings
     * given.
     *
     * @param int|null $year      if null, act as a getter, if not null, set the year and return current instance.
     * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday)
     * @param int|null $dayOfYear first day of year included in the week #1
     *
     * @return int|static
     */
    public function isoWeekYear($year = null, $dayOfWeek = null, $dayOfYear = null)
    {
        return $this->weekYear(
            $year,
            $dayOfWeek ?? 1,
            $dayOfYear ?? 4
        );
    }

    /**
     * Set/get the week number of year using given first day of week and first
     * day of year included in the first week. Or use US format if no settings
     * given (Sunday / Jan 6).
     *
     * @param int|null $year      if null, act as a getter, if not null, set the year and return current instance.
     * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday)
     * @param int|null $dayOfYear first day of year included in the week #1
     *
     * @return int|static
     */
    public function weekYear($year = null, $dayOfWeek = null, $dayOfYear = null)
    {
        $dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0;
        $dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1;

        if ($year !== null) {
            $year = (int) round($year);

            if ($this->weekYear(null, $dayOfWeek, $dayOfYear) === $year) {
                return $this->avoidMutation();
            }

            $week = $this->week(null, $dayOfWeek, $dayOfYear);
            $day = $this->dayOfWeek;
            $date = $this->year($year);
            switch ($date->weekYear(null, $dayOfWeek, $dayOfYear) - $year) {
                case 1:
                    $date = $date->subWeeks(26);

                    break;
                case -1:
                    $date = $date->addWeeks(26);

                    break;
            }

            $date = $date->addWeeks($week - $date->week(null, $dayOfWeek, $dayOfYear))->startOfWeek($dayOfWeek);

            if ($date->dayOfWeek === $day) {
                return $date;
            }

            return $date->next($day);
        }

        $year = $this->year;
        $day = $this->dayOfYear;
        $date = $this->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);

        if ($date->year === $year && $day < $date->dayOfYear) {
            return $year - 1;
        }

        $date = $this->avoidMutation()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);

        if ($date->year === $year && $day >= $date->dayOfYear) {
            return $year + 1;
        }

        return $year;
    }

    /**
     * Get the number of weeks of the current week-year using given first day of week and first
     * day of year included in the first week. Or use ISO format if no settings
     * given.
     *
     * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday)
     * @param int|null $dayOfYear first day of year included in the week #1
     *
     * @return int
     */
    public function isoWeeksInYear($dayOfWeek = null, $dayOfYear = null)
    {
        return $this->weeksInYear(
            $dayOfWeek ?? 1,
            $dayOfYear ?? 4
        );
    }

    /**
     * Get the number of weeks of the current week-year using given first day of week and first
     * day of year included in the first week. Or use US format if no settings
     * given (Sunday / Jan 6).
     *
     * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday)
     * @param int|null $dayOfYear first day of year included in the week #1
     *
     * @return int
     */
    public function weeksInYear($dayOfWeek = null, $dayOfYear = null)
    {
        $dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0;
        $dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1;
        $year = $this->year;
        $start = $this->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
        $startDay = $start->dayOfYear;
        if ($start->year !== $year) {
            $startDay -= $start->daysInYear;
        }
        $end = $this->avoidMutation()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
        $endDay = $end->dayOfYear;
        if ($end->year !== $year) {
            $endDay += $this->daysInYear;
        }

        return (int) round(($endDay - $startDay) / 7);
    }

    /**
     * Get/set the week number using given first day of week and first
     * day of year included in the first week. Or use US format if no settings
     * given (Sunday / Jan 6).
     *
     * @param int|null $week
     * @param int|null $dayOfWeek
     * @param int|null $dayOfYear
     *
     * @return int|static
     */
    public function week($week = null, $dayOfWeek = null, $dayOfYear = null)
    {
        $date = $this;
        $dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0;
        $dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1;

        if ($week !== null) {
            return $date->addWeeks(round($week) - $this->week(null, $dayOfWeek, $dayOfYear));
        }

        $start = $date->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
        $end = $date->avoidMutation()->startOfWeek($dayOfWeek);
        if ($start > $end) {
            $start = $start->subWeeks(26)->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek);
        }
        $week = (int) ($start->diffInDays($end) / 7 + 1);

        return $week > $end->weeksInYear($dayOfWeek, $dayOfYear) ? 1 : $week;
    }

    /**
     * Get/set the week number using given first day of week and first
     * day of year included in the first week. Or use ISO format if no settings
     * given.
     *
     * @param int|null $week
     * @param int|null $dayOfWeek
     * @param int|null $dayOfYear
     *
     * @return int|static
     */
    public function isoWeek($week = null, $dayOfWeek = null, $dayOfYear = null)
    {
        return $this->week(
            $week,
            $dayOfWeek ?? 1,
            $dayOfYear ?? 4
        );
    }
}
