<?php

declare(strict_types=1);

class EstablishmentEvent extends ObjectModel
{
    public const TABLE = 'establishment_event';

    public const EVENT_CUSTOMER_JOIN = 'customer_join';

    public const EVENT_CUSTOMER_LEAVE = 'customer_leave';

    public const EVENT_CUSTOMER_UPDATE = 'customer_update';

    public const EVENT_CUSTOMER_DISABLED = 'customer_disabled';

    public const EVENT_ORDER_UPDATED = 'order_updated';

    /**
     * @var int
     */
    public $id_myvetshop_clinique;

    /**
     * Values are : customer_join, customer_leave, customer_update, customer_disabled, order_updated.
     *
     * @var string
     */
    public $event;

    /**
     * Customer ID (only if event_type is customer_xxx).
     *
     * @var int|null
     */
    public $id_customer;

    /**
     * Raw customer event data (JSON format, only filled if id_customer is not null).
     *
     * @var string|null
     */
    public $customer_data;

    /**
     * Order ID (only if event_type is order_updated).
     *
     * @var int|null
     */
    public $id_order;

    /**
     * Raw order event data (JSON format, only filled if id_order is not null).
     *
     * @var string|null
     */
    public $order_data;

    /**
     * @var string Object creation date
     */
    public $date_add;

    /**
     * @var array<string, mixed>
     *
     * @see ObjectModel::$definition
     */
    public static $definition
        = [
            'table' => self::TABLE,
            'primary' => 'id_establishment_event',
            'multilang' => false,
            'multilang_shop' => false,
            'fields' => [
                'id_myvetshop_clinique' => ['type' => self::TYPE_INT],
                'event' => ['type' => self::TYPE_STRING],
                'id_customer' => ['type' => self::TYPE_INT],
                'customer_data' => ['type' => self::TYPE_STRING],
                'id_order' => ['type' => self::TYPE_INT],
                'order_data' => ['type' => self::TYPE_STRING],
                'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false],
            ],
        ];

    public static function install(): bool
    {
        $query = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . static::TABLE . '` (
              `id_establishment_event` INT(11) NOT NULL AUTO_INCREMENT,
              `id_myvetshop_clinique` INT(11) NOT NULL,
              `event` VARCHAR(20) NOT NULL,
              `id_customer` INT(11) DEFAULT NULL,
              `customer_data` LONGTEXT DEFAULT NULL,
              `id_order` INT(11) DEFAULT NULL,
              `order_data` LONGTEXT DEFAULT NULL,
              `date_add` DATETIME NOT NULL,
               PRIMARY KEY (`id_establishment_event`)
            );';

        return Db::getInstance()->execute($query);
    }

    /**
     * @return array<mixed>
     */
    public static function createOrderData(Order $order): array
    {
        $orderState = $order->getCurrentOrderState();
        if (!$orderState) {
            throw new Exception('Order without status');
        }
        $context = Context::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['product_reference'], 2),
                'total_refunded_tax_incl' => round($orderLine['total_refunded_tax_incl'], 2),
            ];
        }

        return $ret;
    }

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

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

        $ret->event = $event;
        $ret->id_customer = (int) $customer->id;
        $ret->customer_data = \json_encode(self::createCustomerData($customer)) ?: null;

        $clinique = Clinique::getCliniqueByGroupId((int) $customer->id_default_group);
        if ($clinique && $clinique->id && !$clinique->deleted) {
            $ret->id_myvetshop_clinique = $clinique->id;
        }

        return $ret;
    }

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

        $ret->event = $event;
        $ret->id_order = (int) $order->id;
        $ret->order_data = \json_encode(self::createOrderData($order)) ?: null;

        $clinique = Clinique::getCliniqueByCarrierId((int) $order->id_carrier);
        if ($clinique && $clinique->id) {
            $ret->id_myvetshop_clinique = $clinique->id;
        }

        return $ret;
    }
}
