<?php

class Agro_Utils_Date
{
    public const FORMAT_PT_BR = 'dd/MM/yyyy';
    public const FORMAT_ISO_8601 = 'yyyy-MM-dd';

    private Zend_Date $zendDate;
    private string $format;

    /**
     * @param string $date
     * @param string $format
     * @throws Zend_Date_Exception
     * @throws Zend_Validate_Exception
     */
    public function __construct(string $date, string $format = self::FORMAT_ISO_8601)
    {
        if (!$this->formatIsValid($date, $format)) {
            throw new Zend_Validate_Exception('Data com formato inválido.');
        }

        $this->zendDate = new Zend_Date($date, $format);
        $this->format = $format;
    }

    /**
     * @param int $numberDays
     * @return void
     * @throws Zend_Date_Exception
     */
    public function addDays(int $numberDays): void
    {
        $this->zendDate->addDay($numberDays);
    }

    /**
     * @param string $date
     * @param string $format
     * @return Agro_Utils_Date
     * @throws Zend_Date_Exception
     * @throws Zend_Validate_Exception
     */
    public static function create(string $date, string $format = self::FORMAT_ISO_8601): Agro_Utils_Date
    {
        return new Agro_Utils_Date($date, $format);
    }

    /**
     * @param Agro_Utils_Date $dateCompare
     * @return bool
     * @throws Zend_Date_Exception
     */
    public function equals(Agro_Utils_Date $dateCompare): bool
    {
        return $this->zendDate->equals($dateCompare->getDate());
    }

    public function formatIsValid(string $date, string $format): bool
    {
        return (new Zend_Validate_Date(['format' => $format]))->isValid($date);
    }

    public function getDate(): Zend_Date
    {
        return $this->zendDate;
    }

    /**
     * @param Agro_Utils_Date $dateCompare
     * @return bool
     * @throws Zend_Date_Exception
     */
    public function isEarlier(Agro_Utils_Date $dateCompare): bool
    {
        return $this->zendDate->isEarlier($dateCompare->getDate());
    }

    /**
     * @param Agro_Utils_Date $dateCompare
     * @return bool
     * @throws Zend_Date_Exception
     */
    public function isLater(Agro_Utils_Date $dateCompare): bool
    {
        return $dateCompare->getDate()->isLater($this->zendDate);
    }

    public function toString(string $newFormat = ''): string
    {
        $format = $this->format;

        if (!empty($newFormat)) {
            if (!$this->inArrayFormat($newFormat)) {
                throw new Zend_Validate_Exception('Formato inválido.');
            }

            $format = $newFormat;
        }

        return $this->zendDate->toString($format);
    }

    private function inArrayFormat(string $format): bool
    {
        return in_array(
            $format,
            [
                self::FORMAT_PT_BR,
                self::FORMAT_ISO_8601,
            ]
        );
    }
}