<?php

/**
 * Vvveb
 *
 * Copyright (C) 2022  Ziadin Givan
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

/*
Name: AI Assistant
Slug: ai-assistant
Category: tools
Url: https://www.vvveb.com
Description: Add an AI assistant to the content editor and site editor. Supports OpenAI, Anthropic Claude, Google Gemini, DeepSeek, Groq, Mistral, xAI Grok and OpenRouter with streaming responses, reasoning blocks, file attachments, tool calls and an optional server side proxy that hides api keys from the browser.
Author: givanz
Version: 0.2
Thumb: ai-assistant.svg
Author url: https://www.vvveb.com
Settings: /admin/index.php?module=plugins/ai-assistant/settings
*/

use Vvveb\System\Event;
use Vvveb\System\MCP;
use Vvveb\Plugins\AiAssistant\Install;

if (! defined('V_VERSION')) {
	die('Invalid request!');
}

class AiAssistantPlugin {
	public function addTinyMce() {
		Event::on('Vvveb\System\Core\View', 'compile', __CLASS__, function ($template, $htmlFile, $tplFile, $vTpl, $view) {
			//insert the ai assistant button and scripts on post, product, menu and editor pages
			// editor uses left sidebar ai-assistant.html (public/admin/default/src/editor/ai-assistant.html), not modal
			$targets = [
				'content' . DS . 'post.html'                => 'ai-assistant-ui.js',
				'product' . DS . 'product.html'             => 'ai-assistant-ui.js',
				'content' . DS . 'menus' . DS . 'menu.html'  => 'ai-assistant-ui.js',
			];

			$isEditor = ($template === 'editor' . DS . 'editor.html');
			// translations domain page gets the provider adapters so the inline bulk translate button can use VvvebAi
			$isTranslations = ($template === 'localization' . DS . 'translations' . DS . 'domain.html');
			
			/*
			if (! isset($targets[$template]) && ! $isEditor && ! $isTranslations) {
				return [$template, $htmlFile, $tplFile, $vTpl, $view];
			}*/

			$defaults = [
				'key'          => '',
				'url'          => '',//https://api.openai.com/v1/chat/completions
				'model'        => '',//gpt-4o-mini
				'temperature'  => 0,
				'max_tokens'   => 120000,
				'context_size' => 1000000,
				'image_model'  => 'dall-e-3',
				'image_size'   => '1024x1024',
				'provider'     => 'openai',
				'system_prompt'=> '',
				'api_mode'     => 'proxy', // direct = browser calls the provider, proxy = relayed through admin backend to hide api keys
				'proxy_url'    => '/admin/index.php?module=plugins/ai-assistant/proxy',
				'session_header' => 'x-vvveb-session', // upstream header carrying the chat session id (empty disables)
				// per-provider api keys (openai compatible providers included)
				'openai_key'    => '',
				'anthropic_key' => '',
				'google_key'    => '',
				'deepseek_key'  => '',
				'groq_key'      => '',
				'mistral_key'   => '',
				'xai_key'       => '',
				'openrouter_key'=> '',
				'opencode_key'  => '',
				'nim_key'       => '',
			];

			$settingsKeys = array_keys($defaults);
			$options      = \Vvveb\getSetting('ai-assistant', $settingsKeys);
			$options       = $options + $defaults;
			//escape html entities so settings can not break out of the script tag
			$json   = json_encode($options, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
			
			$scriptTag = "<script src=\"/mcp.js\"></script>";
			//provider adapters must load before the ai assistant script (left sidebar uses ai-core directly)
			$scripts = ['js/ai-core.js', 'js/aiProviderOpenAI.js', 'js/aiProviderAnthropic.js', 'js/aiProviderGoogle.js', 'ai-assistant-ui.js'];
			//if (isset($targets[$template])) $scripts[] = $targets[$template];
			// editor: provider adapters already needed for left sidebar ai-assistant.html, no modal script
			foreach ($scripts as $script) {
				$scriptTag = $scriptTag ?? '';
				$scriptTag .= "<script src=\"../../plugins/ai-assistant/$script\"></script>";
			}
			$scriptTag .= "<script src=\"/js/ai-assistant.js\"></script>";
			$script = "<script>window.aiAssistantOptions = $json;</script>" . $scriptTag;


			$systemPrompt = MCP::systemPrompt();
			$tools = MCP::tools(null, 'api');
			$tools = json_encode($tools);
			
			$mcp = 'Vvveb.Ai.systemPromt = ' . json_encode($systemPrompt);
			$mcp .= 'Vvveb.Ai.systemPromt = ' . json_encode($systemPrompt);
			unset($scriptTag);

			$vTpl->addCommand('body|append', $script);

			return [$template, $htmlFile, $tplFile, $vTpl, $view];
		});
	}

	public function install() {
		$install = new Install();
		$install->run();
	}

	public function admin() {
		// create sessions table on first activation
		Event::on('Vvveb\System\Extensions\Plugins', 'setup', __CLASS__, function ($pluginName, $siteId) {
			if ($pluginName == 'ai-assistant') {
				$this->install();
			}

			return [$pluginName, $siteId];
		});

		// add admin menu item
		$admin_path = \Vvveb\adminPath();
		Event::on('Vvveb\Controller\Base', 'init-menu', __CLASS__, function ($menu) use ($admin_path) {
			$menu['plugins']['items']['ai-assistant'] = [
				'name'     => 'AI Assistant',
				'url'      => $admin_path . 'index.php?module=plugins/ai-assistant/settings',
				'icon-img' => PUBLIC_PATH . 'plugins/ai-assistant/ai-assistant.svg',
			];

			return [$menu];
		});

		//insert ask ai button in tinymce editor toolbar for post and product admin templates
		$this->addTinyMce();
		
	}

	public function __construct() {
		if (APP == 'admin') {
			$this->admin();
		}
	}
}

$aiAssistantPlugin = new AiAssistantPlugin();
