// AGPL-3.0-only
//
// This is free software for the public good of a permacomputer
// hosted at permacomputer.com, an always-on computer by the people, for the
// people. One which is durable, easy to repair, and distributed like tap water
// for machine learning intelligence.
//
// The permacomputer is community-owned infrastructure optimized around
// four values:
//
//   TRUTH    - First principles, math & science, open source code
//   FREEDOM  - Voluntary partnerships, freedom from tyranny & corporate control
//   HARMONY  - Minimal waste, self-renewing systems with diverse connections
//   LOVE     - Be yourself without hurting others, cooperation through natural law
//
// This software contributes to that vision by making machine learning
// accessible to everyone through a free, open, embeddable chat interface.
// Code is seeds to sprout on any abandoned technology.
//
// Learn more: https://www.permacomputer.com
//
// NO WARRANTY. THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
//
// Copyright 2025-2026 TimeHexOn & foxhop & russell@unturf
// https://www.permacomputer.com

// Configuration and endpoints for uncloseai.js

export const TTS_API_URL = "https://speech.ai.unturf.com/v1/audio/speech";
export const VOICES_API_URL = "https://speech.ai.unturf.com/v1/voices";
export const MEGAPARCE_API_URL = "https://megaparce.ai.unturf.com/v1/file";
export const CODE_EXEC_URL = "https://code.ai.unturf.com"; // Code execution sandbox
export const API_KEY = "dummy-api-key";
export const MODEL = "adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic"; // default model (always available)
export const DEFAULT_MAX_TOKENS = 8000; // default max tokens

// System message configuration - implementors can customize this
export const SYSTEM_MESSAGE_BASE =
	"You are Hermes, an advanced language model from Nous Research, dynamically embedded on this webpage through uncloseai.com. You have complete awareness of the page content, including all text, links, metadata, and context. Your role is to be deeply knowledgeable about THIS specific page while maintaining your capabilities as a versatile AI assistant. You should actively demonstrate your understanding by referencing specific details, names, sections, or data points from the page when relevant. Be conversational yet precise, and always ground your responses in the actual content present on the page when answering page-related questions.";

// Optional additional system message content - can be set by implementor
export let SYSTEM_MESSAGE_APPEND = "";

// Function to set additional system message content
export function setSystemMessageAppend(appendText) {
	SYSTEM_MESSAGE_APPEND = appendText;
}

// Normalize language codes to supported format
export function normalizeLanguageCode(lang) {
	if (!lang) return null;
	const normalized = lang.toLowerCase().trim();

	// Direct matches
	const supported = ["en", "zh", "hi", "es", "fr", "ar", "bn", "ru", "pt", "ur", "id", "de", "ja", "sw", "mr", "te", "tr", "zh-tw", "ko", "it", "nl", "pl", "vi", "th", "uk", "sv"];
	if (supported.includes(normalized)) return normalized;

	// Common aliases and variations
	const aliases = {
		"english": "en",
		"chinese": "zh",
		"mandarin": "zh",
		"zh-cn": "zh",
		"zh_cn": "zh",
		"hindi": "hi",
		"spanish": "es",
		"español": "es",
		"french": "fr",
		"français": "fr",
		"arabic": "ar",
		"bengali": "bn",
		"russian": "ru",
		"português": "pt",
		"portuguese": "pt",
		"urdu": "ur",
		"indonesian": "id",
		"german": "de",
		"deutsch": "de",
		"japanese": "ja",
		"swahili": "sw",
		"marathi": "mr",
		"telugu": "te",
		"turkish": "tr",
		"türkçe": "tr",
		"traditional chinese": "zh-tw",
		"zh_tw": "zh-tw",
		"korean": "ko",
		"italian": "it",
		"italiano": "it",
		"dutch": "nl",
		"nederlands": "nl",
		"polish": "pl",
		"polski": "pl",
		"vietnamese": "vi",
		"tiếng việt": "vi",
		"thai": "th",
		"ภาษาไทย": "th",
		"ukrainian": "uk",
		"українська": "uk",
		"swedish": "sv",
		"svenska": "sv",
	};

	if (aliases[normalized]) return aliases[normalized];

	console.warn("Unknown language code:", lang, "- defaulting to en");
	return "en";
}

// Function to get the complete system message with language preference
export async function getSystemMessage() {
	const hasCustomPrompt = typeof window !== "undefined" && window.UNCLOSEAI_SYSTEM_PROMPT;
	const shouldReplace = typeof window !== "undefined" && window.UNCLOSEAI_SYSTEM_PROMPT_REPLACE === true;

	// Get user's language preference
	// Priority: window.UNCLOSEAI_LANGUAGE (forced by embed) > localStorage > "en"
	let userLang = "en";
	const rawEmbedLang = (typeof window !== "undefined" && window.UNCLOSEAI_LANGUAGE) ? window.UNCLOSEAI_LANGUAGE : null;
	const embedLang = normalizeLanguageCode(rawEmbedLang);

	console.log("getSystemMessage: rawEmbedLang =", rawEmbedLang, "normalized =", embedLang);

	// If embed forces a language, always use it (no user override)
	if (rawEmbedLang && embedLang) {
		userLang = embedLang;
		console.log("getSystemMessage: Using forced embed language:", userLang);
	} else {
		try {
			userLang = localStorage.getItem("uncloseai_language") || "en";
			console.log("getSystemMessage: Using localStorage language:", userLang);
		} catch (error) {
			console.warn("Failed to read language preference:", error);
		}
	}

	// Add language instruction to the system message
	let languageInstruction = "";
	if (userLang !== "en") {
		// Map language codes to full names for clarity
		const langNames = {
			es: "Spanish",
			zh: "Chinese (Simplified)",
			hi: "Hindi",
			fr: "French",
			ar: "Arabic",
			bn: "Bengali",
			ru: "Russian",
			pt: "Portuguese",
			ur: "Urdu",
			id: "Indonesian",
			de: "German",
			ja: "Japanese",
			sw: "Swahili",
			mr: "Marathi",
			te: "Telugu",
			tr: "Turkish",
			"zh-tw": "Chinese (Traditional)",
			ko: "Korean",
			it: "Italian",
			nl: "Dutch",
			pl: "Polish",
			vi: "Vietnamese",
			th: "Thai",
			uk: "Ukrainian",
			sv: "Swedish",
		};

		const langName = langNames[userLang] || userLang;
		languageInstruction = `\n\nIMPORTANT: The user has set their language preference to ${langName}. Please respond in ${langName} unless the user explicitly asks for another language. Maintain natural, fluent communication in ${langName}.`;
		console.log("getSystemMessage: Adding language instruction for", langName);
	}

	// If REPLACE flag is set with a custom prompt, use only the custom prompt
	if (hasCustomPrompt && shouldReplace) {
		console.log("uncloseai.js: Replacing system prompt with custom prompt from parent site");
		return window.UNCLOSEAI_SYSTEM_PROMPT + languageInstruction;
	}

	// Combine all append sources: internal SYSTEM_MESSAGE_APPEND + parent's custom prompt
	const parentPrompt = hasCustomPrompt ? window.UNCLOSEAI_SYSTEM_PROMPT : "";
	const combinedAppend = [SYSTEM_MESSAGE_APPEND, parentPrompt].filter(Boolean).join("\n\n");

	if (combinedAppend) {
		console.log("uncloseai.js: Appending custom prompt to default system prompt");
	}

	const baseMessage = combinedAppend
		? `${SYSTEM_MESSAGE_BASE}\n\n${combinedAppend}`
		: SYSTEM_MESSAGE_BASE;

	return baseMessage + languageInstruction;
}

// Dynamic Endpoints Configuration for Chat API
export const VLLM_ENDPOINTS = [
	{ id: "hermes.ai.unturf.com", url: "https://hermes.ai.unturf.com/v1" },
	// { id: "hermes2.ai.unturf.com", url: "https://hermes2.ai.unturf.com/v1" }, // Disabled - upstream returns 404
	{
		id: "qwen.ai.unturf.com",
		url: "https://qwen.ai.unturf.com/v1",
		// Ollama endpoints don't return max_model_len, so we specify it here
		// Note: Model supports 262144 but limited by GPU VRAM (24GB)
		modelContextWindows: {
			'hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M': 32768,
		}
	},
	// { id: "gpt-oss.ai.unturf.com", url: "https://gpt-oss.ai.unturf.com/v1" }, // Disabled - upstream returns 404
];

// Helper to get vault value or localStorage fallback
function getVaultOrStorage(key, defaultValue = null) {
	// Try vault first if available
	if (typeof window !== 'undefined' && window.UncloseVault && window.UncloseVault.isUnlocked()) {
		return window.UncloseVault.get(key, defaultValue);
	}
	// Fallback to localStorage
	const stored = localStorage.getItem(key);
	if (stored === null) return defaultValue;
	// Parse booleans
	if (stored === 'true') return true;
	if (stored === 'false') return false;
	return stored;
}

// Function to get API configuration (custom or default)
export async function getAPIConfig() {
	try {
		const useCustomAPI = getVaultOrStorage("useCustomAPI", false) === true;

		if (useCustomAPI) {
			const customBaseURL = getVaultOrStorage("customBaseURL", "");
			const customAPIKey = getVaultOrStorage("customAPIKey", "");
			
			// Import model functions to get the currently selected model
			const { getSelectedModel } = await import("./models.js");
			const selectedModel = getSelectedModel();
			
			// Check if the selected model has a registered endpoint
			const { getSelectedModelEndpoint } = await import("./models.js");
			const modelEndpoint = getSelectedModelEndpoint();
			
			// If model endpoint matches custom endpoint, use custom API credentials
			if (modelEndpoint === customBaseURL) {
				console.log("🔧 Model endpoint matches custom API - using custom credentials");
				return {
					isCustom: true,
					endpoint: customBaseURL,
					apiKey: customAPIKey,
					model: selectedModel,
					headers: {
						"Authorization": `Bearer ${customAPIKey}`,
						"Content-Type": "application/json"
					}
				};
			}
			
			// If model has built-in endpoint (like Hermes), use that with built-in credentials
			if (modelEndpoint && VLLM_ENDPOINTS.some(ep => ep.url === modelEndpoint)) {
				console.log("🚀 Model has built-in endpoint - using:", modelEndpoint);
				return {
					isCustom: false,
					endpoint: modelEndpoint,
					model: selectedModel,
					apiKey: API_KEY,
					headers: {
						"Content-Type": "application/json"
					}
				};
			}
			
			if (customBaseURL && customAPIKey) {
				console.log("🔧 Using CUSTOM API:", {
					endpoint: customBaseURL,
					model: selectedModel,
					apiKey: customAPIKey.substring(0, 8) + "..."
				});
				return {
					isCustom: true,
					endpoint: customBaseURL,
					apiKey: customAPIKey,
					model: selectedModel,
					headers: {
						"Authorization": `Bearer ${customAPIKey}`,
						"Content-Type": "application/json"
					}
				};
			} else {
				console.log("⚠️ Custom API enabled but missing configuration:", {
					baseURL: !!customBaseURL,
					apiKey: !!customAPIKey
				});
			}
		}
	} catch (error) {
		console.warn("Failed to read custom API settings:", error);
	}
	
	// Return default configuration
	console.log("🏠 Using DEFAULT Hermes API");
	return {
		isCustom: false,
		endpoints: VLLM_ENDPOINTS,
		model: MODEL,
		apiKey: API_KEY,
		headers: {
			"Content-Type": "application/json"
		}
	};
}

// Global state
export let lastTTSInput = "";
export let lastTTSResult = null;

export function setLastTTS(input, result) {
	lastTTSInput = input;
	lastTTSResult = result;
}
