<?php

namespace App\Services;

use App\ChatSession;
use App\UserToken;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;

class AIApiService
{

    protected $client;
    protected $baseUri;
    protected $authEmail;
    protected $authPassword;

    public function __construct()
    {
        $this->baseUri = config('services.snwolley_ai.service_url');
        $this->authEmail = config('services.snwolley_ai.auth_email');
        $this->authPassword = config('services.snwolley_ai.auth_password');

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

    public function authenticate()
    {
        $response = $this->client->post('/api/v1/login_or_signup', [
            'json' => [
                'email' => $this->authEmail,
                'password' => $this->authPassword,
            ],
        ]);

        $data = json_decode($response->getBody(), true);

        if (isset($data['token'])) {
            UserToken::query()->updateOrCreate(
                ['user_id' => \auth()->id()],
                ['token' => $data['token']]
            );
        }

        return $data;
    }

    public function sendMessage($message, $agent = 1)
    {
        try {
            $token = $this->getToken();
            $chatSession = $this->getChatSession();
            $updatedMessage = "Give me an sms campaign message considering this: '$message'";

            $response = $this->client->post('/api/v2/stream', [
                'headers' => [
                    'Authorization' => 'Bearer ' . $token,
                ],
                'json' => [
                    'message' => $updatedMessage,
                    'agent' => $agent,
                    'stream' => false,
                    'chat_id' => $chatSession ? $chatSession->chat_id : null,
                ],
            ]);

            $responseData = json_decode($response->getBody(), true);

            // Update or create chat session with the received chat_id
            if (isset($responseData['chat_id'])) {
                $this->updateChatSession($responseData['chat_id']);
            }

            return $responseData;
        } catch (ClientException $e) {
            if ($e->getResponse()->getStatusCode() == 401) {
                // Token has expired, re-authenticate and try again
                $this->reauthenticate();
                return $this->sendMessage($message, $agent);
            }
            throw $e;
        }
    }

    protected function getToken()
    {
        $userToken = UserToken::query()->where('user_id', auth()->id())->first();

        if (!$userToken) {
            return $this->reauthenticate();
        }

        return $userToken->token;
    }

    protected function reauthenticate()
    {
        $authResponse = $this->authenticate();
        return $authResponse['token'];
    }

    protected function getChatSession()
    {
        $userId = auth()->id();
        $dynamicUserId = session()->get('dynamic_user') ? session()->get('dynamic_user')->id : null;

        return ChatSession::query()->where('user_id', $userId)
            ->where('dynamic_user_id', $dynamicUserId)
            ->first();
    }

    protected function updateChatSession($chatId)
    {
        $userId = auth()->id();
        $dynamicUserId = session()->get('dynamic_user') ? session()->get('dynamic_user')->id : null;

        ChatSession::query()->updateOrCreate(
            [
                'user_id' => $userId,
                'dynamic_user_id' => $dynamicUserId,
            ],
            ['chat_id' => $chatId]
        );
    }

}
