<?php

namespace Unit\Entity\Factory;

use Myvetshop\Module\Clinique\Entity\EstablishmentEvent;
use Myvetshop\Module\Clinique\Entity\Factory\EstablishmentEventFactory;
use Myvetshop\Module\Clinique\Repository\MyvetshopCliniqueRepository;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use PrestaShop\PrestaShop\Adapter\LegacyContext;

class EstablishmentEventFactoryTest extends TestCase
{
    private EstablishmentEventFactory $establishmentEventFactory;

    /**
     * @var \Context&MockObject
     */
    private \Context $context;

    /**
     * @var LegacyContext&MockObject
     */
    private LegacyContext $legacyContext;

    /**
     * @var MyvetshopCliniqueRepository&MockObject
     */
    private MyvetshopCliniqueRepository $cliniqueRepository;

    protected function setUp(): void
    {
        $this->cliniqueRepository = $this->createMock(MyvetshopCliniqueRepository::class);
        $this->legacyContext = $this->createMock(LegacyContext::class);
        $this->context = $this->createMock(\Context::class);
        $this->context->language = $this->createMock(\Language::class);
        $this->context->language->id = 1;
        $this->legacyContext
            ->method('getContext')
            ->willReturn($this->context);

        $this->establishmentEventFactory = new EstablishmentEventFactory(
            $this->cliniqueRepository,
            $this->legacyContext
        );
    }

    public function testCreateCustomerEvent(): void
    {
        $customerMock = $this->getMockBuilder(\Customer::class)
                            ->disableOriginalConstructor()
                            ->getMock();

        $customerMock->id = 1;
        $customerMock->email = 'test@example.com';
        $customerMock->firstname = 'Test';
        $customerMock->lastname = 'User';

        $event = EstablishmentEvent::EVENT_CUSTOMER_JOIN;

        $result = $this->establishmentEventFactory->createCustomerEvent($event, $customerMock);

        $this->assertInstanceOf(EstablishmentEvent::class, $result);
        $this->assertSame($event, $result->event);
        $this->assertSame($customerMock->id, $result->idCustomer);
        $this->assertEquals(
            [
                'id_customer' => $customerMock->id,
                'email' => $customerMock->email,
                'firstname' => $customerMock->firstname,
                'lastname' => $customerMock->lastname,
            ],
            $result->customerData
        );
    }

    public function testCreateOrderEvent(): void
    {
        $orderMock = $this->getMockBuilder(\Order::class)
            ->disableOriginalConstructor()
            ->getMock();

        $orderStateMock = $this->createMock(\OrderState::class);
        $orderStateMock->id = 3;
        $orderStateMock->color = '#000000';
        $orderStateMock->name = [1 => 'En cours de préparation'];

        $orderMock->id = 1;
        $orderMock->reference = 'TestOrderRef123';
        $orderMock
            ->method('getCurrentOrderState')
            ->willReturn($orderStateMock);
        $orderMock
            ->method('getOrderDetailList')
            ->willReturn([]);
        $orderMock->id_customer = 2;

        $event = EstablishmentEvent::EVENT_ORDER_UPDATED;

        $result = $this->establishmentEventFactory->createOrderEvent($event, $orderMock);

        $this->assertInstanceOf(EstablishmentEvent::class, $result);
        $this->assertSame($event, $result->event);
        $this->assertSame($orderMock->id, $result->idOrder);
        $this->assertEquals(
            [
                'id_order' => $orderMock->id,
                'reference' => $orderMock->reference,
                'id_customer' => $orderMock->id_customer,
                'status' => [
                    'id_order_state' => $orderStateMock->id,
                    'color' => $orderStateMock->color,
                    'name' => $orderStateMock->name[$this->context->language->id],
                ],
                'invoice_date' => $orderMock->invoice_date,
                'total_paid_tax_incl' => $orderMock->total_paid_tax_incl,
                'lines' => [],
            ],
            $result->orderData
        );
    }
}
