<?php

namespace Mtc\Plugins\Agent\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Log;
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\Models\AIChatHistory;
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',
        ]);

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

        $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 = 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: " . print_r($userMessage, true));

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

            Log::info("Response from Agent: " . print_r($response, true));

            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];
        }
    }
    /**
     * @description Audio whisper (Please Dont use this in production yet)
     * */
    public function audioWhisper(Request $request) {
        $request->validate([
            'audio_file' => 'required|file|mimes:mp3,wav,aac,mp4,webm',
        ]);

        $filename = 'whisper_upload_' . uniqid() . '.webm';

        $audioFile = $request->file('audio_file');
        $path = $audioFile->storeAs('temp_whisper', $filename);
        $fullPath = storage_path('app/' . $path);

        try {
            $client = OpenAI::client($this->openai_api_key);
            $response = $client->audio()->transcribe([
                'model' => 'whisper-1',
                'file' => fopen($fullPath, 'r'),
                'response_format' => 'verbose_json',
                'timestamp_granularities' => ['segment', 'word'],
            ]);
            return response()->json($response);

        } catch (\Exception $e) {
            return response()->json(['error' => 'Transcription failed: ' . $e->getMessage()], 500);
        } finally {
            // Clean up the uploaded file
            if (file_exists($fullPath)) {
                unlink($fullPath);
            }
        }
    }


    public function audioTTS(Request $request)
    {
        $headers = [
            'Content-Type'        => 'audio/mpeg', // Matches 'tts-1' default output
            'Content-Disposition' => 'inline; filename="speech.mp3"', // 'inline' allows browser playback
            'Cache-Control'       => 'no-cache',
            'X-Accel-Buffering'   => 'no', // Important for Nginx to disable buffering
        ];
        $client = OpenAI::client($this->openai_api_key);
        return response()->stream(function () use ($client , $request) {

            // Request the stream from OpenAI

            $stream = $client->audio()->speechStreamed([
                'model' => 'tts-1',
                'input' => $request->input('text'),
                'voice' => 'alloy',
            ]);

            // Iterate and Output
            foreach ($stream as $chunk) {
                echo $chunk;

                // Force PHP to send the buffer to the browser immediately
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
            }

        }, 200, $headers);

    }

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

}
