<?php
/*
 * @copyright Copyright (c) 2018 Ubiquiti Networks, Inc.
 * @see https://www.ubnt.com/
 */


declare(strict_types=1);


namespace SmsNotifier\Factory;

use SmsNotifier\Data\NotificationData;
use SmsNotifier\Service\Logger;
use SmsNotifier\Service\UcrmApi;

class NotificationDataFactory
{
    /**
     * @var UcrmApi
     */
    private $ucrmApi;

    public function __construct(
        UcrmApi $ucrmApi
    ) {
        $this->ucrmApi = $ucrmApi;
    }

    public function getObject($jsonData): NotificationData
    {
        $notificationData = new NotificationData();
        $notificationData->uuid = $jsonData['uuid'];
        $notificationData->changeType = $jsonData['changeType'];
        $notificationData->entity = $jsonData['entity'];
        $notificationData->entityId = $jsonData['entityId'] ? (int) $jsonData['entityId'] : null;
        $notificationData->eventName = $jsonData['eventName'];
        $notificationData->message = $jsonData['extraData']['message'] ?? null;

        // Intentar poblar los datos de la entidad directamente desde el webhook
        if (isset($jsonData['extraData']['entity'])) {
            $entityData = $jsonData['extraData']['entity'];
            if (empty($entityData['clientId']) && isset($jsonData['extraData']['entityBeforeEdit']['clientId'])) {
                $entityData['clientId'] = $jsonData['extraData']['entityBeforeEdit']['clientId'];
            }
            switch ($notificationData->entity) {
                case 'client':
                    $notificationData->clientData = $entityData;
                    break;
                case 'invoice':
                    $notificationData->invoiceData = $entityData;
                    break;
                case 'payment':
                    $notificationData->paymentData = $entityData;
                    break;
                case 'service':
                    $notificationData->serviceData = $entityData;
                    break;
            }
        } elseif (isset($jsonData['extraData']['entityBeforeEdit'])) {
            $entityData = $jsonData['extraData']['entityBeforeEdit'];
            switch ($notificationData->entity) {
                case 'client':
                    $notificationData->clientData = $entityData;
                    break;
                case 'invoice':
                    $notificationData->invoiceData = $entityData;
                    break;
                case 'payment':
                    $notificationData->paymentData = $entityData;
                    break;
                case 'service':
                    $notificationData->serviceData = $entityData;
                    break;
            }
        }

        // Check if the given webhook exists. Skip for manual triggers.
        if ($notificationData->uuid !== 'manual-trigger') {
            $this->ucrmApi->query('webhook-events/' . $notificationData->uuid);
        }

        $this->resolveUcrmData($notificationData);

        return $notificationData;
    }

    private function resolveUcrmData(NotificationData $notificationData): void
    {
        switch ($notificationData->entity) {
            case 'client':
                $notificationData->clientId = $notificationData->entityId;
                break;
            case 'invoice':
                $notificationData->clientId = $notificationData->invoiceData['clientId'] ?? $this->getInvoiceData($notificationData)['clientId'] ?? null;
                break;
            case 'payment':
                $notificationData->clientId = $notificationData->paymentData['clientId'] ?? $this->getPaymentData($notificationData)['clientId'] ?? null;
                break;
            case 'service':
                $notificationData->clientId = $notificationData->serviceData['clientId'] ?? $this->getServiceData($notificationData)['clientId'] ?? null;
                break;
        }
        if ($notificationData->clientId) {
            $this->getClientData($notificationData);
        }
    }

    private function getClientData(NotificationData $notificationData)
    {
        if (empty($notificationData->clientData) && $notificationData->clientId) {
            $notificationData->clientData = $this->ucrmApi->query('clients/' . $notificationData->clientId);
        }

        if ($notificationData->message) {
            $notificationData->clientData['message'] = $notificationData->message;
        }
        return $notificationData->clientData;
    }

    private function getPaymentData(NotificationData $notificationData)
    {
        if (empty($notificationData->paymentData) && $notificationData->entityId) {
            $notificationData->paymentData = $this->ucrmApi->query('payments/' . $notificationData->entityId);
        }
        return $notificationData->paymentData;
    }

    private function getInvoiceData(NotificationData $notificationData)
    {
        if (empty($notificationData->invoiceData) && $notificationData->entityId) {
            $notificationData->invoiceData = $this->ucrmApi->query('invoices/' . $notificationData->entityId);
        }
        return $notificationData->invoiceData;
    }

    private function getServiceData(NotificationData $notificationData)
    {
        if (empty($notificationData->serviceData) && $notificationData->entityId) {
            $notificationData->serviceData = $this->ucrmApi->query('clients/services/' . $notificationData->entityId);
        }

        if (($notificationData->serviceData['suspensionReasonId'] ?? null) !== null) {
            $notificationData->serviceData['stopReason'] = $this->ucrmApi->query(
                'service-suspension-reasons/' . $notificationData->serviceData['suspensionReasonId']
            )['name'] ?? null;
        }

        return $notificationData->serviceData;
    }
}
