<?php

namespace Mtc\Plugins\Agent\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Mtc\Plugins\Agent\Agents\Observers\TokenUsageObserver;
use Mtc\Plugins\Agent\Agents\PharmacyAgent;
use Mtc\Plugins\Agent\Events\ChatGenerated;
use Mtc\Plugins\Agent\Events\Thinking;
use Mtc\Plugins\Agent\Http\Middlewares\AgentAnonymous;
use Mtc\Plugins\Agent\Models\AIChatHistory;
use Mtc\Plugins\Agent\Models\ChatGuestUser;
use NeuronAI\Chat\Messages\UserMessage;
use OpenAI;

class ChatController extends Controller
{
    protected string $openai_api_key;

    public function __construct()
    {
        $this->openai_api_key = config('neuron.openai.key');
    }


    public function sendMessage(Request $request)
    {
        $request->validate([
            'message' => 'required|string|max:2000',
        ]);

        $user = Auth::user();
        if (!$user || !isset($user->id)) {
            return response()->json(['error' => 'Guest session not initialised'], 401);
        }

        $message = $request->input('message');
        $guestId = (string) $user->id;

        $productName = '';
        $productId = Null;
        $chatResponse = '';

        $settings = new AgentSettingsController();

        $access = $settings->getTokenUsage();


        if (!$access) {
            $chatResponse = "Sorry, the AI assistance is currently unavailable. Please try again later or contact us.";
            ChatGenerated::dispatch($chatResponse, $productName, $productId, null, $guestId);
        }
        else {
            Thinking::dispatch($guestId);

            $productOutput = $this->AgentCommunicate($message, $guestId);

            $productName = $productOutput->name ?? '';
            $chatResponse = $productOutput->response ?? '';
            $productId = $productOutput->productId ?? null;

            $item = null;
            if (!empty($productId)) {
                $item = new \Item();
                $item->Get_Item($productId);
            }


            ChatGenerated::dispatch($chatResponse, $productName, $productId, $item, $guestId);

        }

        return response()->json(['status' => 'message sent']);
    }
    private function AgentCommunicate($message, $guestId)
    {
        try {
            $observer = new TokenUsageObserver();
            // 1. Initialize Agent
            $agent = PharmacyAgent::make()->setGuestId($guestId);
            $agent->observe($observer, 'inference-stop');

            $userMessage = new UserMessage($message);

            Log::info('Sending message to Agent', [
                'guest_id' => $guestId,
                'message_length' => strlen($message),
            ]);

            $response = $agent->structured($userMessage);

            Log::info('Response from Agent', [
                'guest_id' => $guestId,
                'product_id' => $response->productId ?? null,
                'response_length' => isset($response->response) ? strlen($response->response) : 0,
            ]);

            return $response;

        } catch (\Exception $e) {
            Log::error('Agent communication failed: ' . $e->getMessage());
            // Return a structure that matches your expected output object so $productOutput->response doesn't fail
            return (object) ['response' => "I'm sorry, I encountered an error.", 'name' => '', 'productId' => null];
        }
    }

    public function session(Request $request)
    {
        $user = Auth::user();
        if (!$user || !isset($user->id)) {
            return response()->json(['error' => 'Guest session not initialised'], 500);
        }

        return response()->json(['guestId' => (string) $user->id]);
    }

    public function resetSession(Request $request)
    {
        $guestId = (string) Str::uuid();

        Cookie::queue(
            AgentAnonymous::COOKIE_NAME,
            $guestId,
            AgentAnonymous::COOKIE_TTL_MINUTES,
            '/',
            null,
            $request->secure(),
            true,
            false,
            'lax'
        );

        Auth::setUser(new ChatGuestUser([
            'id' => $guestId,
            'name' => 'Guest',
        ]));

        return response()->json(['guestId' => $guestId]);
    }

    public function chatHistory() : array|object
    {
        try {
            $ChatHistories = AIChatHistory::orderBy('updated_at', 'desc')->paginate(50);
            return response()->json(['messages' => $ChatHistories->items()], 200);
        }
        catch (\Exception $e) {
            Log::error('Failed to retrieve chat histories: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to retrieve chat histories'], 500);
        }
    }

}
