<?php

namespace Lc\CaracoleBundle\Solver\Price;

use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface;
use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
use Lc\CaracoleBundle\Model\Order\OrderShopInterface;

class PriceSolver
{
    protected ProductPriceSolver $productPriceSolver;
    protected OrderProductPriceSolver $orderProductPriceSolver;
    protected OrderShopPriceSolver $orderShopPriceSolver;

    public function __construct(
            ProductPriceSolver $productPriceSolver,
            OrderProductPriceSolver $orderProductPriceSolver,
            OrderShopPriceSolver $orderShopPriceSolver
    ) {
        $this->productPriceSolver = $productPriceSolver;
        $this->orderProductPriceSolver = $orderProductPriceSolver;
        $this->orderShopPriceSolver = $orderShopPriceSolver;
    }

    public function __call($name, $arguments)
    {
        if (strpos($name, 'apply') === false) {
            $entity = $arguments[0];
            $service = '';

            if ($entity instanceof ProductPropertyInterface) {
                $service = 'productPriceSolver';
            }

            if ($entity instanceof OrderProductInterface) {
                $service = 'orderProductPriceSolver';
            }

            if ($entity instanceof OrderShopInterface || is_iterable($entity) || is_array($entity)) {
                $service = 'orderShopPriceSolver';
            }

            if (strlen($service) && $entity && method_exists($this->$service, $name)) {
                if (isset($arguments[1]) && isset($arguments[2]) && isset($arguments[3])) {
                    return $this->$service->$name($entity, $arguments[1], $arguments[2], $arguments[3]);
                } elseif (isset($arguments[1]) && isset($arguments[2])) {
                    return $this->$service->$name($entity, $arguments[1], $arguments[2]);
                } elseif (isset($arguments[1])) {
                    return $this->$service->$name($entity, $arguments[1]);
                } else {
                    return $this->$service->$name($entity);
                }
            } else {
                if (!strlen($service)) {
                    throw new \ErrorException("PriceSolver : le type d'entité n'est pas géré");
                } else {
                    if (!method_exists($this->$service, $name)) {
                        throw new \ErrorException(
                                "PriceSolver : la méthode " . $name . " du service " . $service . " n'existe pas."
                        );
                    }
                }
            }

            return false;
        }
    }
}