<?php

namespace Myvetshop\Module\Clinique\Entity\Factory;

use Doctrine\ORM\EntityNotFoundException;
use Myvetshop\Module\Clinique\Entity\EstablishmentEvent;
use Myvetshop\Module\Clinique\Entity\MyvetshopClinique;
use Myvetshop\Module\Clinique\Repository\MyvetshopCliniqueRepository;
use PrestaShop\PrestaShop\Adapter\LegacyContext;

class EstablishmentEventFactory
{
    private MyvetshopCliniqueRepository $myvetshopCliniqueRepository;

    private LegacyContext $legacyContext;

    public function __construct(
        MyvetshopCliniqueRepository $myvetshopCliniqueRepository,
        LegacyContext $legacyContext
    ) {
        $this->myvetshopCliniqueRepository = $myvetshopCliniqueRepository;
        $this->legacyContext = $legacyContext;
    }

    /**
     * @return array<mixed>
     */
    public function createCustomerData(\Customer $customer): array
    {
        return [
            'id_customer' => (int) $customer->id,
            'email' => (string) $customer->email,
            'firstname' => (string) $customer->firstname,
            'lastname' => (string) $customer->lastname,
        ];
    }

    /**
     * @return array<mixed>
     */
    public function createOrderData(\Order $order): array
    {
        $orderState = $order->getCurrentOrderState();
        if (!$orderState) {
            throw new \Exception('Order without status : ' . $order->id);
        }
        $context = $this->legacyContext->getContext();
        \assert(null !== $context);

        $ret = [
            'id_order' => (int) $order->id,
            'id_customer' => (int) $order->id_customer,
            'reference' => (string) $order->reference,
            'status' => [
                'id_order_state' => (int) $orderState->id,
                'color' => (string) $orderState->color,
                'name' => (string) $orderState->name[$context->language->id],
            ],
            'invoice_date' => $order->invoice_date,
            'total_paid_tax_incl' => round($order->total_paid_tax_incl, 2),
            'lines' => [],
        ];

        foreach ($order->getOrderDetailList() as $orderLine) {
            $ret['lines'][] = [
                'id_order_detail' => (int) $orderLine['id_order_detail'],
                'product_name' => (string) $orderLine['product_name'],
                'product_reference' => (string) $orderLine['product_reference'],
                'product_quantity' => (int) $orderLine['product_quantity'],
                'product_quantity_refunded' => (int) $orderLine['product_quantity_refunded'],
                'total_price_tax_incl' => round($orderLine['total_price_tax_incl'], 2),
                'total_refunded_tax_incl' => round($orderLine['total_refunded_tax_incl'], 2),
            ];
        }

        return $ret;
    }

    public function createCustomerEvent(string $event, \Customer $customer): EstablishmentEvent
    {
        $ret = new EstablishmentEvent();

        $ret->event = $event;
        $ret->idCustomer = (int) $customer->id;
        $ret->customerData = $this->createCustomerData($customer);

        $clinique = $this->myvetshopCliniqueRepository->findByGroupId((int) $customer->id_default_group);

        if (!$clinique) {
            throw EntityNotFoundException::fromClassNameAndIdentifier(MyvetshopClinique::class, [(string) $customer->id_default_group]);
        }

        $ret->clinique = $clinique;

        return $ret;
    }

    public function createOrderEvent(string $event, \Order $order): EstablishmentEvent
    {
        $ret = new EstablishmentEvent();

        $ret->event = $event;
        $ret->idOrder = (int) $order->id;
        $ret->orderData = $this->createOrderData($order);

        $clinique = $this->myvetshopCliniqueRepository->findByCarrierId((int) $order->id_carrier);

        if (!$clinique) {
            throw EntityNotFoundException::fromClassNameAndIdentifier(MyvetshopClinique::class, [(string) $order->id_carrier]);
        }

        $ret->clinique = $clinique;

        return $ret;
    }
}
