<?php

namespace apexl\Io\modules\invoice\services;

use apexl\Io\includes\System;
use apexl\Io\modules\invoice\entities\invoiceProcessQueueEntity;
use apexl\Io\modules\invoice\providers\xeroProvider;
use apexl\Io\modules\invoice\services\invoiceService;
use apexl\Io\modules\payment\entities\paymentEntity;
use apexl\Io\modules\payment\entities\paymentWebhookLogEntity;
use apexl\Io\modules\payment\providers\stripeProvider;
use apexl\Io\modules\product\entities\productEntity;
use apexl\Io\modules\subscription\entities\subscriptionCreditEntity;
use apexl\Io\modules\subscription\entities\subscriptionEntity;
use apexl\Io\services\Database;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class webhookService {

    protected $provider;
    protected $providerName;
    protected $invoiceService;

    public function __construct()
    {
        $this->invoiceService = new invoiceService();
        $this->provider = new xeroProvider($this->invoiceService);
        $this->providerName = 'xero';
    }

    public function processRequest(Request $request)
    {
        // Webhook logging
        $log = new paymentWebhookLogEntity();
        $log->received = date('Y-m-d H:i:s');
        $log->method = $_SERVER['REQUEST_METHOD'];
        $log->payload = $request->getBody();
        $log->provider = $this->providerName;
        $log->store();

        $logId = $log->id;

        //list($event, $validated, $providerRef, $error, $metadata) = $this->provider->processWebhookRequest($payload); // Process the webhook request
        list($statusCode, $processes) = $this->provider->processWebhookRequest($request); // Process the webhook request

        if ($statusCode != 200) {
            return [$statusCode, "Failed status code " . $statusCode];
        } else {
            $log->validated = true;
            $log->store();
            if (count($processes) > 0) {
                Database::persistRawBatch($processes, 'invoice_process_queue');
            }
        }

        return [200, null];
    }

    public function processQueue()
    {
        $invoiceProcessQueue = new invoiceProcessQueueEntity();
        $items = $invoiceProcessQueue->getUnprocessedItems(); //@todo get unprocessed items

        foreach ($items as $item) {
            $result = $this->provider->processQueueItem($item);
            $invoiceProcessQueue->markItemAsProcessed($item->provider_id, ($result?'':'Item Not Found'));
        }

        return count($items);
    }
}