<?php

namespace Myvetshop\Module\Clinique\Handler;

use Animal;
use Clinique;
use Context;
use Customer;
use Exception;
use Myvetshop\Module\Clinique\Api\CricCrocApi;
use MyvetshopRecommandationProduct;
use Product;
use Recommandation;
use Symfony\Component\Translation\TranslatorInterface;
use Validate;

class RecommandationHandler
{
    /**
     * @var Customer
     */
    private $customer;

    /**
     * @var TranslatorInterface
     */
    private $translator;

    private $api;

    public function __construct(Customer $customer, TranslatorInterface $translator)
    {
        $this->customer = $customer;
        $this->translator = $translator;
        $this->api = new CricCrocApi();
    }

    public function getById(int $recommandationId)
    {
    }

    public function getByCode(string $code): array
    {
        $code = trim(strtoupper($code));

        if (empty($code)) {
            throw new Exception('Le code fourni est invalide');
        }

        if (Recommandation::codeExist($code)) {
            throw new Exception('Le code fourni a déjà été importé');
        }

        $data = $this->api->getRecommandationByCode($code);

        $clinique = Clinique::getByCodePrivilege($data['code']);

        if ($this->customer->isLogged() && !$clinique->hasCustomer($this->customer->id)) {
            throw new Exception('Le code fourni n\'est pas reconnu');
        }

        $products = [];

        $i = 1;

        $productKey = 'productIDmvs' . $i;
        while (array_key_exists($productKey, $data)) {
            $productId = (int) $data[$productKey];

            if ($productId) {
                $products[] = [
                    'entity' => new Product($productId, false, Context::getContext()->language->id),
                    'quantity' => array_key_exists('qteAliment' . $i, $data) ? (int) $data['qteAliment' . $i] : 0,
                    'months' => array_key_exists('transition' . $i . ($i + 1), $data) ? (int) $data['transition' . $i . ($i + 1)] : 0,
                ];
            }

            ++$i;
            $productKey = 'productIDmvs' . $i;
        }

        $data['products'] = $products;

        return $data;
    }

    public function getAll(): array
    {
    }

    public function import(string $code, ?int $animalId = null): Recommandation
    {
        $code = trim(strtoupper($code));

        $data = $this->getByCode($code);

        $species = $data['esp'];
        $animal = new Animal($animalId);

        if (is_null($animalId)) {
            $animal = new Animal();
            $animal->nom = $data['petname'];
            $animal->espece = $data['esp'];
            $animal->race = $data['race'];
            $animal->id_gender = $data['sex'];
            $animal->date_naissance = $data['dob'];
            $animal->id_customer = $this->customer->id;
            $animal->add();
        }

        if (!Validate::isLoadedObject($animal) || $animal->isDeleted()) {
            throw new Exception('L\'animal n\'existe pas');
        }

        if (!$animal->hasCustomer($this->customer->id)) {
            throw new Exception('L\'animal et le client ne correspondent pas');
        }

        if (!$animal->isSpecies($species)) {
            throw new Exception('L\'espèce de la recommandation et de l\'animal ne correspondent pas.');
        }

        //On se prépare à ajouter une nouvelle recommandation. Il faut donc "supprimer" l'ancienne de l'animal
        if ($animal->hasRecommandation()) {
            $animal->getRecommandation()->delete();
        }

        $recommandation = new Recommandation();
        $recommandation->id_animal = $animal->id;
        $recommandation->code_reco = $code;
        $recommandation->id_customer = $this->customer->id;
        $recommandation->date_reco = $data['date'];
        $recommandation->code_clinique = $data['code'];
        $recommandation->petname = $data['petname'];
        $recommandation->espece = $data['esp'];
        $recommandation->race = $data['race'];
        $recommandation->id_gender = $data['sex'];
        $recommandation->activite = $data['act'];
        $recommandation->age = $data['age'];
        $recommandation->date_birth = $data['dob'];
        $recommandation->stade_physio = $data['stadePhysio'];
        $recommandation->pathologie = $data['patho'];
        $recommandation->poids_actuel = $data['actualw'];
        $recommandation->poids_ideal = $data['idealw'];
        $recommandation->be = $data['be'];
        $recommandation->nbr_aliment = $data['nbrAliment'];

        $recommandation->save();

        $previous = null;

        foreach ($data['products'] as $row) {
            $product = $row['entity'];

            $recommandationProduct = new MyvetshopRecommandationProduct();
            $recommandationProduct->id_recommandation = $recommandation->id;
            $recommandationProduct->id_product = (int) $product->id;
            $recommandationProduct->quantity = $row['quantity'];
            $recommandationProduct->months = $row['months'];

            $recommandationProduct->save();

            if (!is_null($previous)) {
                $previous->id_recommandation_product_next = $recommandationProduct->id;
                $previous->save();
            }

            if (!$recommandation->id_recommandation_product) {
                $recommandation->id_recommandation_product = $recommandationProduct->id;
            }

            $previous = $recommandationProduct;
        }

        //On sauvegarde de nouveau la recommandation pour lui permettre de créer le nouveau cartRule
        $recommandation->update();

        return $recommandation;
    }

    public function update(int $recommandationId, int $animalId, int $recommandationProductId): void
    {
        $recommandation = new Recommandation($recommandationId);
        $recommandationProduct = new MyvetshopRecommandationProduct($recommandationProductId);
        $animal = new Animal($animalId);

        if (!Validate::isLoadedObject($recommandation) || !$recommandation->hasCustomer($this->customer->id)) {
            throw new Exception($this->translator->trans('Il n\'est pas possible de modifier cette recommandation.', [], 'Modules.Myvetshopclinique.Shop'));
        }

        if (!Validate::isLoadedObject($animal) || !$animal->hasCustomer($this->customer->id) || !$animal->isSpecies($recommandation->espece)) {
            throw new Exception($this->translator->trans('Il n\'est pas possible de modifier cette recommandation.', [], 'Modules.Myvetshopclinique.Shop'));
        }

        if (!Validate::isLoadedObject($recommandationProduct) || $recommandationProduct->id_recommandation != $recommandation->id) {
            throw new Exception($this->translator->trans('Il n\'est pas possible de modifier cette recommandation.', [], 'Modules.Myvetshopclinique.Shop'));
        }

        $recommandation->id_animal = $animal->id;
        $recommandation->id_recommandation_product = $recommandationProduct->id;

        $recommandation->update();

        //Maintenant on recalcule la ration de l'animal
        $recommandationProduct = new MyvetshopRecommandationProduct($recommandation->id_recommandation_product);

        $animal->ration = (int) $recommandationProduct->quantity;

        $animal->save();
    }

    public function delete(int $recommandationId): void
    {
        $recommandation = new Recommandation($recommandationId);

        if (!Validate::isLoadedObject($recommandation) || !$recommandation->hasCustomer($this->customer->id)) {
            throw new Exception($this->translator->trans('Il n\'est pas possible de supprimer cette recommandation.', [], 'Modules.Myvetshopclinique.Shop'));
        }

        $recommandation->delete();
    }

    public function getPdf(int $recommandationId): ?string
    {
        $recommandation = new Recommandation($recommandationId);

        if (Validate::isLoadedObject($recommandation) && $recommandation->hasCustomer((int) $this->customer->id)) {
            return $this->api->getPdf($recommandation->code_reco);
        }

        return null;
    }
}
