<?php

/**
 * Created by Aurélien RICHAUD (01/08/2017 16:51)
 */
class CliniqueHolidays extends ObjectModel
{
    const TABLE = 'myvetshop_clinique_holidays';

    /**
     * @var int
     */
    public $id_myvetshop_clinique;

    /**
     * @var string
     */
    public $date_alerte;

    /**
     * @var string
     */
    public $date_debut;

    /**
     * @var string
     */
    public $date_fin;

    /**
     * @var string
     */
    public $message_alerte;

    /**
     * @var string
     */
    public $message;

    /**
     * @see ObjectModel::$definition
     */
    public static $definition = [
        'table' => self::TABLE,
        'primary' => 'id_myvetshop_clinique_holidays',
        'multilang' => false,
        'multilang_shop' => false,
        'fields' => [
            // Clés étrangères
            'id_myvetshop_clinique' => ['type' => self::TYPE_INT, 'required' => true],
            'date_alerte' => ['type' => self::TYPE_DATE, 'required' => false],
            'date_debut' => ['type' => self::TYPE_DATE, 'required' => true, 'validate' => 'isDate'],
            'date_fin' => ['type' => self::TYPE_DATE, 'required' => true, 'validate' => 'isDate'],
            'message_alerte' => ['type' => self::TYPE_STRING, 'required' => false, 'size' => 1000],
            'message' => ['type' => self::TYPE_STRING, 'required' => true, 'size' => 1000],
        ],
    ];

    public function getMessage(): ?string
    {
        if ($this->hasAlertActive()) {
            return $this->message_alerte;
        }

        if ($this->isActive()) {
            return $this->message;
        }

        return null;
    }

    public function hasAlertActive(): bool
    {
        $alert = DateTime::createFromFormat('Y-m-d', $this->date_alerte);
        $start = $this->getStartDate();

        return !is_null($start) && $alert->getTimestamp() > 0 && $alert->getTimestamp() < $start->getTimestamp();
    }

    public function isActive(): bool
    {
        $now = new DateTime();
        $start = $this->getStartDate();
        $end = $this->getEndDate();

        return !is_null($start) && !is_null($end) && ($start->getTimestamp() <= $now->getTimestamp()) && ($now->getTimestamp() <= $end->getTimestamp());
    }

    public function getStartDate(): ?DateTime
    {
        return $this->getDate($this->date_debut);
    }

    public function getEndDate(): ?DateTime
    {
        return $this->getDate($this->date_fin);
    }

    public function getAlertDate(): ?DateTime
    {
        return $this->getDate($this->date_alerte);
    }

    protected function getDate(string $date): ?DateTime
    {
        $dateTime = DateTime::createFromFormat('Y-m-d', $date);

        return $dateTime->getTimestamp() > 0 ? $dateTime : null;
    }

    public function getClinique(): ?Clinique
    {
        $clinique = new Clinique($this->id_myvetshop_clinique);

        return Validate::isLoadedObject($clinique) ? $clinique : null;
    }

    public static function getCliniqueMessage(int $cliniqueId): ?string
    {
        $holidays = self::getHolidays($cliniqueId);

        if (empty($holidays)) {
            $holidays = self::getHolidaysSoon($cliniqueId);
        }

        $holiday = array_shift($holidays);

        return $holiday ? $holiday->getMessage() : null;
    }

    /**
     * Congé en cours pour la clinique (entre date d'alerte et fin de congé !)
     */
    public static function getCurrentHolliday(int $cliniqueId): ?CliniqueHolidays
    {
        return self::getByCliniqueId($cliniqueId)[0] ?? null;
    }

    /**
     * @param int $cliniqueId
     *
     * @return CliniqueHolidays[]
     */
    public static function getHolidaysSoon(int $cliniqueId): array
    {
        return array_filter(self::getByCliniqueId($cliniqueId), function (CliniqueHolidays $cliniqueHolidays) {
            return $cliniqueHolidays->hasAlertActive();
        });
    }

    /**
     * @param int $cliniqueId
     *
     * @return CliniqueHolidays[]
     */
    public static function getHolidays(int $cliniqueId): array
    {
        return array_filter(self::getByCliniqueId($cliniqueId), function (CliniqueHolidays $cliniqueHolidays) {
            return $cliniqueHolidays->isActive();
        });
    }

    public static function hasCliniqueOnHolidaysSoon(int $cliniqueId): bool
    {
        return !empty(self::getHolidaysSoon($cliniqueId));
    }

    public static function hasCliniqueOnHolidays(int $cliniqueId): bool
    {
        return !empty(self::getHolidays($cliniqueId));
    }

    /**
     * Liste les congés en cours pour une clinique
     *
     * @return CliniqueHolidays[]
     *
     * @throws PrestaShopDatabaseException
     */
    public static function getByCliniqueId(int $cliniqueId): array
    {
        $query = (new DbQuery())
            ->select(self::$definition['primary'])
            ->from(self::TABLE)
            ->where('id_myvetshop_clinique=' . $cliniqueId)
            ->where(' CURDATE() BETWEEN date_debut AND date_fin OR (date_alerte NOT LIKE "0000-00-00" AND "' . date('Y-m-d') . '" BETWEEN date_alerte AND date_debut)');

        $list = array_column(Db::getInstance()->executeS($query), self::$definition['primary']);

        return array_map(function ($cliniqueHolidaysId) {
            return new self($cliniqueHolidaysId);
        }, $list);
    }

    public static function get(int $cliniqueHolidayId): ?self
    {
        $cliniqueHoliday = new self($cliniqueHolidayId);

        return Validate::isLoadedObject($cliniqueHoliday) ? $cliniqueHoliday : null;
    }

    public static function install(): bool
    {
        $query = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . static::TABLE . '` (
              `id_myvetshop_clinique_holidays`  INT(11) NOT NULL AUTO_INCREMENT,
			  `id_myvetshop_clinique` INT(11) NOT NULL,
			  `date_alerte` DATE NULL,
			  `date_debut` DATE NOT NULL,
			  `date_fin` DATE NOT NULL,
			  `message_alerte` TEXT NULL,
			  `message` TEXT NOT NULL,			  
			   PRIMARY KEY (id_myvetshop_clinique_holidays)
			);';

        return Db::getInstance()->execute($query);
    }
}
