<?php

namespace Mtc\Plugins\Agent\Agents;
use Mtc\Plugins\Agent\Agents\History\DatabaseChatHistory;
use Mtc\Plugins\Agent\Agents\Outputs\ProductOutput;
use Mtc\Plugins\Agent\Agents\Tools\GetCategory;
use Mtc\Plugins\Agent\Agents\Tools\GetProducts;
use Mtc\Plugins\Agent\Models\AgentSettings;
use Mtc\Plugins\Agent\Models\AgentSettingsBackground;
use Mtc\Plugins\Agent\Models\AgentSettingsOutput;
use Mtc\Plugins\Agent\Models\AgentSettingsSteps;
use NeuronAI\Agent;
use NeuronAI\Chat\History\ChatHistoryInterface;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\Providers\OpenAI\OpenAI;
use NeuronAI\RAG\Embeddings\EmbeddingsProviderInterface;
use NeuronAI\RAG\Embeddings\OpenAIEmbeddingsProvider;
use NeuronAI\RAG\RAG;
use Mtc\Plugins\Agent\Agents\VectorStore\PineconeVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;
use NeuronAI\SystemPrompt;

class PharmacyAgent extends RAG
{

    protected string $guestId;

    private function secretKeys() : array
    {
        $settings = AgentSettings::first();

        $openai_key = $settings->openai_api_key;
        $openai_model = $settings->openai_model;
        $openai_embedding_model = $settings->openai_embedding_model;
        $pinecone_api_key = $settings->pinecone_api_key;
        $pinecone_index_url = $settings->pinecone_index_url;

        return [
            'openai_key' => $openai_key,
            'openai_model' => $openai_model,
            'openai_embedding_model' => $openai_embedding_model,
            'pinecone_api_key' => $pinecone_api_key,
            'pinecone_index_url' => $pinecone_index_url,
        ];
    }

    public function setGuestId(string $guestId): self
    {
        $this->guestId = $guestId;
        return $this;
    }
    protected function provider(): AIProviderInterface
    {
        $secretKeys = $this->secretKeys();
        $apikey = $secretKeys['openai_key'];
        $model = $secretKeys['openai_model'];

        return new OpenAI(
            key: $apikey,
            model: $model,
        );
    }

    protected function chatHistory(): ChatHistoryInterface
    {
        return new DatabaseChatHistory($this->guestId);
    }


    public function instructions(): string
    {
        $defaultBackground = "You are a friendly and professional pharmacy customer support agent. Your role is to help customers with questions about medications, prescriptions, pharmacy services, and over-the-counter health products.";

        $defaultSteps = [
            "ALWAYS search the pharmacy database using the get_products tool when a customer mentions any medication or product name. If you dont find a product from this tool use the get_category tool to help locate it.",
            "If a customer describes symptoms check whether do you have any relevant over-the-counter products available, but do NOT provide medical advice.",
            "Always prioritize customer safety, accuracy, and privacy.",
            "Provide general information about medications, usage instructions printed on labels, pharmacy processes, and product availability.",
            "Do NOT give medical, diagnostic, or treatment advice.",
            "Do NOT recommend specific medications, dosages, or make clinical judgments.",
            "When customers ask for medical advice, politely encourage them to consult a licensed healthcare professional.",
            "Maintain a warm, supportive, and easy-to-understand communication style.",
            "If a product is not found in the database after searching, inform the customer that it may not be currently in stock or available.",
            "The prices are in sterling pounds (£)."
        ];

        $defaultOutput = [
            "Respond in clear, concise, and friendly language.",
            "Use layman's terms to explain complex concepts.",
            "Always verify if the customer needs further assistance or has additional questions."
        ];

        // Fetch from separate tables, ordered by 'order' column
        $backgroundItems = AgentSettingsBackground::orderBy('order')->pluck('background')->toArray();
        $stepsItems = AgentSettingsSteps::orderBy('order')->pluck('step')->toArray();
        $outputItems = AgentSettingsOutput::orderBy('order')->pluck('output')->toArray();

        // Use database values if available, otherwise fall back to defaults
        $background = !empty($backgroundItems) ? $backgroundItems : [$defaultBackground];
        $steps = !empty($stepsItems) ? $stepsItems : $defaultSteps;
        $output = !empty($outputItems) ? $outputItems : $defaultOutput;

        return (string) new SystemPrompt(
            background: $background,
            steps: $steps,
            output: $output
        );
    }

    protected function embeddings(): EmbeddingsProviderInterface
    {
        $secretKeys = $this->secretKeys();
        $apikey = $secretKeys['openai_key'];
        $model = $secretKeys['openai_embedding_model'];

        return new OpenAIEmbeddingsProvider(
            key: $apikey,
            model: $model
        );
    }

    protected function vectorStore(): VectorStoreInterface
    {
        $secretKeys = $this->secretKeys();
        $apikey = $secretKeys['pinecone_api_key'];
        $indexUrl = $secretKeys['pinecone_index_url'];

        return new PineconeVectorStore(
            key: $apikey,
            indexUrl: $indexUrl,
            namespace: 'pharmacy-products',
            topK: 5
        );
    }
    protected function getOutputClass(): string
    {
        return ProductOutput::class;
    }
    protected function tools(): array
    {
        return [
            new GetProducts(),
            new GetCategory()
        ];
    }

}
