<?php

declare(strict_types=1);

require_once __DIR__ . \DIRECTORY_SEPARATOR . '..' . \DIRECTORY_SEPARATOR . '..' . \DIRECTORY_SEPARATOR . 'classes' . \DIRECTORY_SEPARATOR . 'Recommandation.php';
require_once __DIR__ . \DIRECTORY_SEPARATOR . '..' . \DIRECTORY_SEPARATOR . '..' . \DIRECTORY_SEPARATOR . 'classes' . \DIRECTORY_SEPARATOR . 'Animal.php';
require_once __DIR__ . \DIRECTORY_SEPARATOR . '..' . \DIRECTORY_SEPARATOR . '..' . \DIRECTORY_SEPARATOR . 'class' . \DIRECTORY_SEPARATOR . 'CricCrocApi.php';

/**
 * @deprecated
 * @see Myvetshop\Module\Clinique\Handler\RecommandationHandler
 * Cette classe permet de gérer les recommandations depuis l'app client ou l'app veto.
 * Elle se comporte comme un Controller et retourne les informations prêtes à serializer en JSON
 */
class RecommandationController
{
    private Customer $customer;

    public function __construct(Customer $customer)
    {
        $this->customer = $customer;
    }

    /**
     * @return array<string, mixed>|Recommandation
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function actionCricCrocGetReco(string $codeReco)
    {
        $codeReco = trim(strtoupper($codeReco));
        // Check si le client n'a pas déjà importé ce code sur son compte
        $db = Db::getInstance(false);
        $sql = 'SELECT COUNT(id_recommandation) as numberOfReco
             FROM `' . _DB_PREFIX_ . 'recommandation` `r`
             WHERE `r`.`id_customer` = ' . (int) $this->customer->id . ' AND `r`.`deleted` = 0 AND `r`.`code_reco` = "' . $db->escape($codeReco) . '"';

        $result = $db->getRow($sql);

        if (!is_array($result) || !isset($result['numberOfReco']) || $result['numberOfReco'] > 0) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => 'Le code fourni a déjà été importé',
            ];
        }

        if ('' == $codeReco) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => 'Le code fourni est invalide',
            ];
        }

        // Récupération des infos de recommandation depuis le site CricCroc
        $api = new CricCrocApi();
        try {
            $recoJson = $api->getRecoJson($codeReco);
            $reco = $api->parseRecoJson($recoJson);
            $reco->code_reco = $codeReco;
        } catch (Exception $e) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => "Le code fourni n'est pas reconnu",
            ];
        }

        // Check correspondance clinique client et clinique de la recommandation
        $group = new Group($this->customer->id_default_group);
        $groupName = $group->name[1];

        if (!str_contains($reco->code_clinique, $groupName)) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => "Le code fourni n'est pas reconnu",
            ];
        }

        return $reco;
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function actionCricCrocDelete(int $idReco): array
    {
        if (!$idReco) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => "L'identifiant de la recommandation est invalide",
            ];
        }

        $recommandation = new Recommandation((int) $idReco);

        if ($recommandation->id_customer != $this->customer->id) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => 'Le client ne correspond pas à la recommandation',
            ];
        }

        if (!$recommandation->id) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => "La recommandation n'existe pas",
            ];
        }

        $recommandation->deleted = true;
        $recommandation->update();

        return $this->serializeRecommandation($recommandation);
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function actionCricCrocUpdate(int $idReco, int $idAnimal, ?int $idProduct = null, ?int $ration = null): array
    {
        if (!$idReco) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => "L'identifiant de la recommandation est invalide",
            ];
        }

        if (!$idAnimal) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => "L'identifiant de l'animal est invalide",
            ];
        }

        $recommandation = new Recommandation($idReco);

        if (!$recommandation->id || $recommandation->deleted) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => "La recommandation n'existe pas",
            ];
        }

        $animal = new Animal($idAnimal);

        if (!$animal->id) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => "L'animal n'existe pas",
            ];
        }

        if ($animal->id_customer != $this->customer->id) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => "L'animal et le client ne correspondent pas",
            ];
        }

        if ($recommandation->id_customer != $this->customer->id) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => 'La recommandation et le client ne correspondent pas',
            ];
        }

        // Animal a deja une reco ? Si la reco n'est pas la meme on la supprime
        $oldReco = $animal->getRecommandation();
        if ($oldReco && $oldReco->id != $recommandation->id) {
            $oldReco->deleted = true;
            $oldReco->update();
        }

        $recommandation->id_animal = $animal->id;
        $recommandation->update();

        // TODO : A voir pour supprimer ça d'ici
        if (null != $idProduct && null !== $ration) {
            $produit = new Product($idProduct);

            if (!$produit->id) {
                header('HTTP/1.0 400 Bad Request');

                return [
                    'error' => "Le produit n'existe pas",
                ];
            }

            $animal->ration = $ration;
            $animal->id_product = $produit->id;
            $animal->update();
        }

        return $this->serializeRecommandation($recommandation);
    }

    /**
     * @return array<string, mixed>
     */
    public function actionCricCrocCheckCodeReco(string $codeReco): array
    {
        $reco = $this->actionCricCrocGetReco($codeReco);

        if (!$reco instanceof Recommandation) {
            return $reco;
        }

        return $this->serializeRecommandation($reco);
    }

    /**
     * @return array<string, mixed>
     */
    public function actionCricCrocGetRecoById(int $idReco): array
    {
        $recommandation = new Recommandation($idReco);

        if (!$recommandation->id || $recommandation->deleted) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => 'La recommandation n\'existe pas',
            ];
        }

        if ((int) $recommandation->id_customer !== (int) $this->customer->id) {
            header('HTTP/1.0 400 Bad Request');

            return [
                'error' => 'La recommandation et le client ne correspondent pas',
            ];
        }

        return $this->serializeRecommandation($recommandation);
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function actionCricCrocList(): array
    {
        $db = Db::getInstance(false);

        $result = $db->executeS(
            'SELECT `r`.*
             FROM `' . _DB_PREFIX_ . 'recommandation` `r`
             WHERE `r`.`id_customer` = ' . (int) $this->customer->id . ' AND `r`.`deleted` = 0'
        );

        $recos = [];
        if (is_array($result)) {
            $recos = ObjectModel::hydrateCollection(
                Recommandation::class, $result
            );
        }

        return array_map(
            [$this, 'serializeRecommandation'],
            $recos
        );
    }

    /**
     * @return array<string, mixed>
     */
    protected function serializeRecommandation(Recommandation $reco): array
    {
        $db = Db::getInstance(false);
        $discount_code = null;
        $result = $db->getRow(
            'SELECT `rule`.code AS discount_code
             FROM `' . _DB_PREFIX_ . 'cart_rule` `rule`
             WHERE `rule`.code = "' . $db->escape($reco->code_reco) . '"
             AND `rule`.quantity > 0
             AND `rule`.active = 1
             ');
        if ($result && is_array($result) && isset($result['discount_code'])) {
            $discount_code = $result['discount_code'];
        }

        return [
            'id' => $reco->id,
            'id_animal' => $reco->id_animal,
            'code_reco' => $reco->code_reco,
            'date_reco' => $reco->date_reco,
            'petname' => $reco->petname,
            'espece' => $reco->espece,
            'race' => $reco->race,
            'id_gender' => $reco->id_gender,
            'activite' => $reco->activite,
            'age' => $reco->age,
            'stade_physio' => $reco->stade_physio,
            'pathologie' => $reco->pathologie,
            'poids_actuel' => $reco->poids_actuel,
            'poids_ideal' => $reco->poids_ideal,
            'be' => $reco->be,
            'nbr_aliment' => $reco->nbr_aliment,
            'product_id_mvs1' => $reco->product_id_mvs1,
            'product_id_mvs2' => $reco->product_id_mvs2,
            'product_id_mvs3' => $reco->product_id_mvs3,
            'qte_aliment1' => $reco->qte_aliment1,
            'qte_aliment2' => $reco->qte_aliment2,
            'qte_aliment3' => $reco->qte_aliment3,
            'transition12' => $reco->transition12,
            'transition23' => $reco->transition23,
            'date_add' => $reco->date_add,
            'date_upd' => $reco->date_upd,
            'deleted' => $reco->deleted,
            'discount_code' => $discount_code,
        ];
    }

    public function actionRecommandationOpenPdf(int $idReco): void
    {
        $recomandation = new Recommandation($idReco);

        \assert(null !== $recomandation->code_reco);

        $api = new CricCrocApi();
        $pdf = $api->getPdf($recomandation->code_reco);

        header('Content-Type: application/pdf');
        header('Content-Disposition: inline; filename=Recommandation-' . $recomandation->code_reco . '.pdf;');
        echo $pdf;
        exit;
    }
}
