<?php

declare(strict_types=1);
/**
 * Created by Aurélien RICHAUD (16/08/2019 11:06)
 */
require_once __DIR__ . DIRECTORY_SEPARATOR . 'AnimalSac.php';

class Animal extends ObjectModel
{
    public const TABLE = 'animal';

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

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

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

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

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

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

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

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

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

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

    /** @var string Object creation date */
    public $date_add;

    /** @var string Object last modification date */
    public $date_upd;

    /** @var bool True if address has been deleted (staying in database as deleted) */
    public $deleted = false;

    /**
     * @see ObjectModel::$definition
     *
     * @var array<string, mixed>
     */
    public static $definition
        = [
            'table' => self::TABLE,
            'primary' => 'id_animal',
            'multilang' => false,
            'multilang_shop' => false,
            'fields' => [
                'id_customer' => ['type' => self::TYPE_INT],
                'espece' => ['type' => self::TYPE_STRING],
                'nom' => ['type' => self::TYPE_STRING],
                'race' => ['type' => self::TYPE_STRING],
                'id_gender' => ['type' => self::TYPE_INT],
                'robe' => ['type' => self::TYPE_STRING],
                'date_naissance' => ['type' => self::TYPE_DATE],
                'ration' => ['type' => self::TYPE_INT],
                'id_product' => ['type' => self::TYPE_INT],
                'id_product_attribute' => ['type' => self::TYPE_INT],
                'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false],
                'date_upd' => ['type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false],
                'deleted' => ['type' => self::TYPE_BOOL],
            ],
        ];

    /**
     * @return array<int, array<string, mixed>>|null
     *
     * @throws PrestaShopDatabaseException
     */
    public function getSacsActuels(): ?array
    {
        $db = Db::getInstance(false);

        $result = $db->executeS(
            'SELECT `as`.* FROM `' . _DB_PREFIX_ . 'animal_sac` `as` '
            . 'WHERE `as`.`id_animal` = ' . (int) $this->id . ' AND `as`.`date_achat` < NOW() AND `as`.`date_fin_estimee` >= NOW() '
            . 'ORDER BY `as`.`date_achat` ASC'
        );

        assert(is_array($result));

        return $result;
    }

    /**
     * @param bool $null_values
     * @param bool $auto_date
     *
     * @throws PrestaShopException
     *
     * {@inheritDoc}
     */
    public function save($null_values = false, $auto_date = true): bool
    {
        if (is_string($this->espece)) {
            $this->espece = trim($this->espece);
        }
        if (is_string($this->nom)) {
            $this->nom = trim($this->nom);
        }
        if (is_string($this->race)) {
            $this->race = trim($this->race);
        }
        if (is_string($this->robe)) {
            $this->robe = trim($this->robe);
        }

        return parent::save($null_values, $auto_date);
    }

    /**
     * @return array<int, int>|null Nombre d'années / mois ou null
     *
     * @throws Exception
     */
    public function getAge(): ?array
    {
        if (!$this->date_naissance || '0000-00-00' == $this->date_naissance) {
            return null;
        }

        $dateDiff = (new DateTime())->diff(new DateTime($this->date_naissance));

        return [$dateDiff->y, $dateDiff->m];
    }

    public function getIdRecoCricCroc(): ?int
    {
        $db = Db::getInstance(false);

        $result = $db->getValue(
            'SELECT MAX(`r`.`id_recommandation`)
             FROM `' . _DB_PREFIX_ . 'recommandation` `r`
             WHERE `r`.`id_animal` = ' . (int) $this->id
            . ' AND `r`.`deleted` = 0'
        );

        if (!$result) {
            return null;
        }

        return (int) $result;
    }

    public function setRationReco(Recommandation $reco): void
    {
        $this->ration = $reco->qte_aliment1;

        if (!$reco->transition12 && $reco->qte_aliment2) {
            $this->ration += $reco->qte_aliment2;
        }
        if (!$reco->transition23 && $reco->qte_aliment3) {
            $this->ration += $reco->qte_aliment3;
        }
        $this->id_product = $reco->product_id_mvs1;
        $this->id_product_attribute = 0;
    }

    /**
     * @return array<string, mixed>|null
     */
    public function getReco(): ?array
    {
        $db = Db::getInstance(false);

        $result = $db->getRow(
            'SELECT `r`.*, `rule`.code AS discount_code, `rule`.quantity AS discount_code_quantity, `rule`.active AS discount_code_active 
             FROM `' . _DB_PREFIX_ . 'recommandation` `r`
             LEFT JOIN `' . _DB_PREFIX_ . 'cart_rule` rule ON `r`.`code_reco` = `rule`.`code`
             WHERE `r`.`id_animal` = ' . (int) $this->id
            . ' AND `r`.`deleted` = 0'
            . ' ORDER BY `r`.`id_recommandation` DESC'
        );

        if (is_array($result)) {
            return $result;
        }

        return null;
    }

    /**
     * @return array<string, mixed>|null
     */
    public function getRecoProduct(int $id_product): ?array
    {
        $db = Db::getInstance(false);

        $result = $db->getRow(
            'SELECT `p`.*, `pl`.*
             FROM `' . _DB_PREFIX_ . 'product_shop` `p`
             LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` `pl` ON `pl`.`id_product` = `p`.`id_product` AND `pl`.`id_lang` = ' . (int) Context::getContext()->language->id
            . ' WHERE `p`.`id_product` = ' . (int) $id_product
            . ' AND `p`.`id_shop` = ' . (int) Context::getContext()->shop->id
        );

        if (is_array($result)) {
            return $result;
        }

        return null;
    }

    public function getRecoProductImageId(int $id_product): ?int
    {
        $db = Db::getInstance(false);

        $result = $db->getValue(
            'SELECT `i`.*
             FROM `' . _DB_PREFIX_ . 'image` `i`
             WHERE `i`.`id_product` = ' . (int) $id_product . ' AND `i`.`cover` = 1'
        );

        if (!$result) {
            return null;
        }

        return (int) $result;
    }

    public static function hydrateAnimalWithReco(Recommandation $reco): Animal
    {
        $animal = new Animal();
        $animal->nom = $reco->petname;
        $animal->espece = strtolower($reco->espece);
        $animal->race = $reco->race;
        $animal->id_gender = $reco->id_gender;
        $animal->setRationReco($reco);
        $animal->deleted = false;

        if ($reco->date_birth && preg_match('/^[0-9]{2}-[0-9]{2}-[0-9]{4}$/', $reco->date_birth)) {
            $date = new DateTime($reco->date_birth, new DateTimeZone('Europe/Paris'));
            $animal->date_naissance = $date->format('Y-m-d');
        }

        return $animal;
    }
}
