<?php

namespace App\Services\Integrations\Tickets\Spoke;

use App\Models\ApiCredential;
use App\Models\FailedTicketHistory;
use App\Services\Integrations\Tickets\TicketIntegrationInterface;
use GuzzleHttp\Client;

/**
 * SpokeIntegration
 */
class SpokeIntegration implements TicketIntegrationInterface
{
    protected $client;
    protected $spokeCredential;
    protected $baseUrl;
    protected $apiKey;

    /**
     * __construct
     *
     * @return void
     */
    public function __construct()
    {
        $this->spokeCredential = ApiCredential::where('slug', 'spoke')->first();
        $this->baseUrl = $this->spokeCredential->url ?? '';
        $this->apiKey = $this->spokeCredential->key ?? '';

        $headers = [
            'Api-key' => $this->apiKey,
            'Authorization' => 'API Key',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ];

        $this->client = new Client([
            'headers' => $headers,
        ]);
    }

    /**
     * getAuthorizedUser
     *
     * @return object
     */
    public function getAuthorizedUser()
    {
        $response = $this->client->request('GET', $this->baseUrl . 'whoami');

        return json_decode($response->getBody()->getContents());
    }
    /**
     * createTicket
     *
     * @param  array $ticketData
     * @return object
     */
    public function createTicket(array $ticketData)
    {
        $message = preg_replace(array('/"/', '/\\\/'), '', str_replace('\n\n', '    .', $ticketData['description']));
        $message = str_replace('\n', '  ', $message);
        $userId = $this->getAuthorizedUser()->user;
        $requestBody = [
            'requester' => $userId,
            'subject' =>  $ticketData['summary'],
            'body' =>  $message,
        ];

        $response = $this->client->request(
            'POST',
            $this->baseUrl . 'requests/',
            ['body' => json_encode($requestBody)]
        );

        return json_decode($response->getBody()->getContents());
    }

    /**
     * getTicket
     *
     * @param  string $requestId
     * @return object
     */
    public function getTicket(string $requestId)
    {
        $response = $this->client->request('GET', $this->baseUrl . 'requests/' . $requestId);

        return json_decode($response->getBody()->getContents());
    }

    /**
     * addCommentToTicket
     *
     * @param  string $requestId
     * @param  string $message
     * @param  string $userId
     * @return object
     */
    public function addCommentToTicket(string $requestId, string $message, string $userId = '')
    {
        $objectId = $this->getTicket($requestId)->id;
        $response = $this->client->request(
            'POST',
            $this->baseUrl . 'requests/' . $objectId . '/messages',
            ['body' => $this->prepareSpokeRequest($message)]
        );

        return json_decode($response->getBody()->getContents());
    }

    /**
     * prepareSpokeRequest
     *
     * @param  string $message
     * @return json
     */
    public function prepareSpokeRequest($message)
    {
        $userId = $this->getAuthorizedUser()->user;
        $message = preg_replace(array('/"/', '/\\\/'), '', str_replace('\n\n', '    .', $message));
        $message = str_replace('\n', '  ', $message);

        $requestBody = [
            'actor' => [
                'kind' => 'User',
                'ref' => $userId,
            ],
            'content' => [
                'message' => [
                    'text' => $message
                ],
            ],
        ];

        return json_encode($requestBody);
    }

    /**
     * Add a commet with attachment to ticket
     * @param string $ticketId
     * @param string $message
     * @param string $userId
     * @param mixed $filePath
     * @param mixed $fileName
     * 
     * @return [type]
     */
    public function addAttachmentToTicket(string $ticketId, string $message, string $userId, $filePath, $fileName)
    {
        $guzzle = $this->client;
        try {
            $response = $guzzle->post('tickets/' . $ticketId . '/reply', [
                'headers' => ['X-Atlassian-Token' => 'no-check'],
                'multipart' => [
                    [
                        'name'     => 'attachments[]',
                        'contents' => fopen($filePath, 'r'),
                    ],
                    [
                        'name' => 'body',
                        'contents' => $message
                    ]
                ],


            ]);
            $response->withHeader('Content-Type', 'multipart/form-data');
            $response = $response->getBody()->getContents();
            $response = json_decode($response, true);
            return true;
        } catch (\Exception $e) {
            logMessage('Spoke attachment add to ticket failed. ' . $e->getMessage(), 'error');
            FailedTicketHistory::create([
                'user_id' => $userId,
                'ticket_id' => $ticketId,
                'description' => $message
            ]);
            // throw new \ErrorException($e);
        }
    }


    /**
     * Get the complete ticket url
     * @param string $requestId
     * 
     * @return [type]
     */
    public function getTicketUrl(string $requestId)
    {
        if (optional($this->spokeCredential)->url) {
            // example https://domain.zendesk.com/agent/tickets/7
            return $requestId ? '<a href="' . $this->spokeCredential->url . 'agent/tickets/' . $requestId . '" target="__blank">:ticket</a>' : '';
        }
        return '';
    }
}
