<?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;

use Carbon\CarbonInterface;
use DateTimeInterface;
use Throwable;

/**
 * Trait Options.
 *
 * Embed base methods to change settings of Carbon classes.
 *
 * Depends on the following methods:
 *
 * @method \Carbon\Carbon|\Carbon\CarbonImmutable shiftTimezone($timezone) Set the timezone
 */
trait Options
{
    use Localization;

    /**
     * Customizable PHP_INT_SIZE override.
     *
     * @var int
     */
    public static $PHPIntSize = PHP_INT_SIZE;

    /**
     * First day of week.
     *
     * @var int|string
     */
    protected static $weekStartsAt = CarbonInterface::MONDAY;

    /**
     * Last day of week.
     *
     * @var int|string
     */
    protected static $weekEndsAt = CarbonInterface::SUNDAY;

    /**
     * Days of weekend.
     *
     * @var array
     */
    protected static $weekendDays = [
        CarbonInterface::SATURDAY,
        CarbonInterface::SUNDAY,
    ];

    /**
     * Format regex patterns.
     *
     * @var array<string, string>
     */
    protected static $regexFormats = [
        'd' => '(3[01]|[12][0-9]|0[1-9])',
        'D' => '(Sun|Mon|Tue|Wed|Thu|Fri|Sat)',
        'j' => '([123][0-9]|[1-9])',
        'l' => '([a-zA-Z]{2,})',
        'N' => '([1-7])',
        'S' => '(st|nd|rd|th)',
        'w' => '([0-6])',
        'z' => '(36[0-5]|3[0-5][0-9]|[12][0-9]{2}|[1-9]?[0-9])',
        'W' => '(5[012]|[1-4][0-9]|0?[1-9])',
        'F' => '([a-zA-Z]{2,})',
        'm' => '(1[012]|0[1-9])',
        'M' => '([a-zA-Z]{3})',
        'n' => '(1[012]|[1-9])',
        't' => '(2[89]|3[01])',
        'L' => '(0|1)',
        'o' => '([1-9][0-9]{0,4})',
        'Y' => '([1-9]?[0-9]{4})',
        'y' => '([0-9]{2})',
        'a' => '(am|pm)',
        'A' => '(AM|PM)',
        'B' => '([0-9]{3})',
        'g' => '(1[012]|[1-9])',
        'G' => '(2[0-3]|1?[0-9])',
        'h' => '(1[012]|0[1-9])',
        'H' => '(2[0-3]|[01][0-9])',
        'i' => '([0-5][0-9])',
        's' => '([0-5][0-9])',
        'u' => '([0-9]{1,6})',
        'v' => '([0-9]{1,3})',
        'e' => '([a-zA-Z]{1,5})|([a-zA-Z]*\\/[a-zA-Z]*)',
        'I' => '(0|1)',
        'O' => '([+-](1[012]|0[0-9])[0134][05])',
        'P' => '([+-](1[012]|0[0-9]):[0134][05])',
        'p' => '(Z|[+-](1[012]|0[0-9]):[0134][05])',
        'T' => '([a-zA-Z]{1,5})',
        'Z' => '(-?[1-5]?[0-9]{1,4})',
        'U' => '([0-9]*)',

        // The formats below are combinations of the above formats.
        'c' => '(([1-9]?[0-9]{4})-(1[012]|0[1-9])-(3[01]|[12][0-9]|0[1-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])[+-](1[012]|0[0-9]):([0134][05]))', // Y-m-dTH:i:sP
        'r' => '(([a-zA-Z]{3}), ([123][0-9]|0[1-9]) ([a-zA-Z]{3}) ([1-9]?[0-9]{4}) (2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]) [+-](1[012]|0[0-9])([0134][05]))', // D, d M Y H:i:s O
    ];

    /**
     * Format modifiers (such as available in createFromFormat) regex patterns.
     *
     * @var array
     */
    protected static $regexFormatModifiers = [
        '*' => '.+',
        ' ' => '[   ]',
        '#' => '[;:\\/.,()-]',
        '?' => '([^a]|[a])',
        '!' => '',
        '|' => '',
        '+' => '',
    ];

    /**
     * Indicates if months should be calculated with overflow.
     * Global setting.
     *
     * @var bool
     */
    protected static $monthsOverflow = true;

    /**
     * Indicates if years should be calculated with overflow.
     * Global setting.
     *
     * @var bool
     */
    protected static $yearsOverflow = true;

    /**
     * Indicates if the strict mode is in use.
     * Global setting.
     *
     * @var bool
     */
    protected static $strictModeEnabled = true;

    /**
     * Function to call instead of format.
     *
     * @var string|callable|null
     */
    protected static $formatFunction;

    /**
     * Function to call instead of createFromFormat.
     *
     * @var string|callable|null
     */
    protected static $createFromFormatFunction;

    /**
     * Function to call instead of parse.
     *
     * @var string|callable|null
     */
    protected static $parseFunction;

    /**
     * Indicates if months should be calculated with overflow.
     * Specific setting.
     *
     * @var bool|null
     */
    protected $localMonthsOverflow;

    /**
     * Indicates if years should be calculated with overflow.
     * Specific setting.
     *
     * @var bool|null
     */
    protected $localYearsOverflow;

    /**
     * Indicates if the strict mode is in use.
     * Specific setting.
     *
     * @var bool|null
     */
    protected $localStrictModeEnabled;

    /**
     * Options for diffForHumans and forHumans methods.
     *
     * @var bool|null
     */
    protected $localHumanDiffOptions;

    /**
     * Format to use on string cast.
     *
     * @var string|null
     */
    protected $localToStringFormat;

    /**
     * Format to use on JSON serialization.
     *
     * @var string|null
     */
    protected $localSerializer;

    /**
     * Instance-specific macros.
     *
     * @var array|null
     */
    protected $localMacros;

    /**
     * Instance-specific generic macros.
     *
     * @var array|null
     */
    protected $localGenericMacros;

    /**
     * Function to call instead of format.
     *
     * @var string|callable|null
     */
    protected $localFormatFunction;

    /**
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
     *             You should rather use the ->settings() method.
     * @see settings
     *
     * Enable the strict mode (or disable with passing false).
     *
     * @param bool $strictModeEnabled
     */
    public static function useStrictMode($strictModeEnabled = true)
    {
        static::$strictModeEnabled = $strictModeEnabled;
    }

    /**
     * Returns true if the strict mode is globally in use, false else.
     * (It can be overridden in specific instances.)
     *
     * @return bool
     */
    public static function isStrictModeEnabled()
    {
        return static::$strictModeEnabled;
    }

    /**
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
     *             You should rather use the ->settings() method.
     *             Or you can use method variants: addMonthsWithOverflow/addMonthsNoOverflow, same variants
     *             are available for quarters, years, decade, centuries, millennia (singular and plural forms).
     * @see settings
     *
     * Indicates if months should be calculated with overflow.
     *
     * @param bool $monthsOverflow
     *
     * @return void
     */
    public static function useMonthsOverflow($monthsOverflow = true)
    {
        static::$monthsOverflow = $monthsOverflow;
    }

    /**
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
     *             You should rather use the ->settings() method.
     *             Or you can use method variants: addMonthsWithOverflow/addMonthsNoOverflow, same variants
     *             are available for quarters, years, decade, centuries, millennia (singular and plural forms).
     * @see settings
     *
     * Reset the month overflow behavior.
     *
     * @return void
     */
    public static function resetMonthsOverflow()
    {
        static::$monthsOverflow = true;
    }

    /**
     * Get the month overflow global behavior (can be overridden in specific instances).
     *
     * @return bool
     */
    public static function shouldOverflowMonths()
    {
        return static::$monthsOverflow;
    }

    /**
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
     *             You should rather use the ->settings() method.
     *             Or you can use method variants: addYearsWithOverflow/addYearsNoOverflow, same variants
     *             are available for quarters, years, decade, centuries, millennia (singular and plural forms).
     * @see settings
     *
     * Indicates if years should be calculated with overflow.
     *
     * @param bool $yearsOverflow
     *
     * @return void
     */
    public static function useYearsOverflow($yearsOverflow = true)
    {
        static::$yearsOverflow = $yearsOverflow;
    }

    /**
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
     *             You should rather use the ->settings() method.
     *             Or you can use method variants: addYearsWithOverflow/addYearsNoOverflow, same variants
     *             are available for quarters, years, decade, centuries, millennia (singular and plural forms).
     * @see settings
     *
     * Reset the month overflow behavior.
     *
     * @return void
     */
    public static function resetYearsOverflow()
    {
        static::$yearsOverflow = true;
    }

    /**
     * Get the month overflow global behavior (can be overridden in specific instances).
     *
     * @return bool
     */
    public static function shouldOverflowYears()
    {
        return static::$yearsOverflow;
    }

    /**
     * Set specific options.
     *  - strictMode: true|false|null
     *  - monthOverflow: true|false|null
     *  - yearOverflow: true|false|null
     *  - humanDiffOptions: int|null
     *  - toStringFormat: string|Closure|null
     *  - toJsonFormat: string|Closure|null
     *  - locale: string|null
     *  - timezone: \DateTimeZone|string|int|null
     *  - macros: array|null
     *  - genericMacros: array|null
     *
     * @param array $settings
     *
     * @return $this|static
     */
    public function settings(array $settings)
    {
        $this->localStrictModeEnabled = $settings['strictMode'] ?? null;
        $this->localMonthsOverflow = $settings['monthOverflow'] ?? null;
        $this->localYearsOverflow = $settings['yearOverflow'] ?? null;
        $this->localHumanDiffOptions = $settings['humanDiffOptions'] ?? null;
        $this->localToStringFormat = $settings['toStringFormat'] ?? null;
        $this->localSerializer = $settings['toJsonFormat'] ?? null;
        $this->localMacros = $settings['macros'] ?? null;
        $this->localGenericMacros = $settings['genericMacros'] ?? null;
        $this->localFormatFunction = $settings['formatFunction'] ?? null;

        if (isset($settings['locale'])) {
            $locales = $settings['locale'];

            if (!\is_array($locales)) {
                $locales = [$locales];
            }

            $this->locale(...$locales);
        }

        if (isset($settings['timezone'])) {
            return $this->shiftTimezone($settings['timezone']);
        }

        return $this;
    }

    /**
     * Returns current local settings.
     *
     * @return array
     */
    public function getSettings()
    {
        $settings = [];
        $map = [
            'localStrictModeEnabled' => 'strictMode',
            'localMonthsOverflow' => 'monthOverflow',
            'localYearsOverflow' => 'yearOverflow',
            'localHumanDiffOptions' => 'humanDiffOptions',
            'localToStringFormat' => 'toStringFormat',
            'localSerializer' => 'toJsonFormat',
            'localMacros' => 'macros',
            'localGenericMacros' => 'genericMacros',
            'locale' => 'locale',
            'tzName' => 'timezone',
            'localFormatFunction' => 'formatFunction',
        ];

        foreach ($map as $property => $key) {
            $value = $this->$property ?? null;

            if ($value !== null) {
                $settings[$key] = $value;
            }
        }

        return $settings;
    }

    /**
     * Show truthy properties on var_dump().
     *
     * @return array
     */
    public function __debugInfo()
    {
        $infos = array_filter(get_object_vars($this), function ($var) {
            return $var;
        });

        foreach (['dumpProperties', 'constructedObjectId'] as $property) {
            if (isset($infos[$property])) {
                unset($infos[$property]);
            }
        }

        $this->addExtraDebugInfos($infos);

        return $infos;
    }

    protected function addExtraDebugInfos(&$infos): void
    {
        if ($this instanceof DateTimeInterface) {
            try {
                if (!isset($infos['date'])) {
                    $infos['date'] = $this->format(CarbonInterface::MOCK_DATETIME_FORMAT);
                }

                if (!isset($infos['timezone'])) {
                    $infos['timezone'] = $this->tzName;
                }
            } catch (Throwable $exception) {
                // noop
            }
        }
    }
}
