using System;
using System.Collections.Generic;
using System.Linq;
using AxCopilot.Models;

namespace AxCopilot.Services;

public class ModelRouterService
{
	private readonly SettingsService _settings;

	public ModelRouterService(SettingsService settings)
	{
		_settings = settings;
	}

	public ModelRouteResult? Route(string userMessage)
	{
		LlmSettings llm = _settings.Settings.Llm;
		if (!llm.EnableAutoRouter)
		{
			return null;
		}
		var (category, num) = IntentDetector.Detect(userMessage);
		if (num < llm.AutoRouterConfidence)
		{
			return null;
		}
		if (category == "general")
		{
			return null;
		}
		List<ModelCapability> list = GatherCandidates(llm);
		if (list.Count == 0)
		{
			return null;
		}
		string currentService = llm.Service.ToLowerInvariant();
		string currentModel = ResolveCurrentModel(llm);
		ModelCapability modelCapability = (from c in list
			where c.Scores.ContainsKey(category)
			orderby c.Scores[category] descending
			select c).FirstOrDefault();
		if (modelCapability == null)
		{
			return null;
		}
		ModelCapability modelCapability2 = list.FirstOrDefault((ModelCapability c) => c.Service.Equals(currentService, StringComparison.OrdinalIgnoreCase) && c.Model.Equals(currentModel, StringComparison.OrdinalIgnoreCase));
		if (modelCapability2 != null && modelCapability2.Scores.TryGetValue(category, out var value) && modelCapability.Scores[category] - value < 0.1)
		{
			return null;
		}
		return new ModelRouteResult(modelCapability.Service, modelCapability.Model, modelCapability.Alias, category, num);
	}

	private List<ModelCapability> GatherCandidates(LlmSettings llm)
	{
		List<ModelCapability> list = new List<ModelCapability>();
		foreach (ModelCapability modelCapability in llm.ModelCapabilities)
		{
			if (modelCapability.Enabled && IsServiceAvailable(llm, modelCapability.Service))
			{
				list.Add(modelCapability);
			}
		}
		List<ModelCapability> defaultCapabilities = GetDefaultCapabilities();
		foreach (ModelCapability def in defaultCapabilities)
		{
			if (IsServiceAvailable(llm, def.Service) && !list.Any((ModelCapability c) => c.Service.Equals(def.Service, StringComparison.OrdinalIgnoreCase) && c.Model.Equals(def.Model, StringComparison.OrdinalIgnoreCase)))
			{
				list.Add(def);
			}
		}
		return list;
	}

	private static bool IsServiceAvailable(LlmSettings llm, string service)
	{
		string text = service.ToLowerInvariant();
		if (1 == 0)
		{
		}
		bool result = text switch
		{
			"gemini" => !string.IsNullOrEmpty(llm.GeminiApiKey), 
			"claude" => !string.IsNullOrEmpty(llm.ClaudeApiKey), 
			"ollama" => !string.IsNullOrEmpty(llm.OllamaEndpoint), 
			"vllm" => !string.IsNullOrEmpty(llm.VllmEndpoint), 
			_ => false, 
		};
		if (1 == 0)
		{
		}
		return result;
	}

	private static string ResolveCurrentModel(LlmSettings llm)
	{
		string service = llm.Service;
		bool flag = ((service == "ollama" || service == "vllm") ? true : false);
		if (flag && !string.IsNullOrEmpty(llm.Model))
		{
			return CryptoService.DecryptIfEnabled(llm.Model, llm.EncryptionEnabled);
		}
		string text = llm.Service.ToLowerInvariant();
		if (1 == 0)
		{
		}
		service = ((text == "gemini") ? llm.GeminiModel : ((!(text == "claude")) ? llm.Model : llm.ClaudeModel));
		if (1 == 0)
		{
		}
		return service;
	}

	public static List<ModelCapability> GetDefaultCapabilities()
	{
		return new List<ModelCapability>
		{
			new ModelCapability
			{
				Service = "gemini",
				Model = "gemini-2.5-flash",
				Alias = "Gemini 2.5 Flash",
				Scores = new Dictionary<string, double>
				{
					["coding"] = 0.7,
					["translation"] = 0.7,
					["analysis"] = 0.85,
					["creative"] = 0.65,
					["document"] = 0.7,
					["math"] = 0.9
				}
			},
			new ModelCapability
			{
				Service = "gemini",
				Model = "gemini-2.5-pro",
				Alias = "Gemini 2.5 Pro",
				Scores = new Dictionary<string, double>
				{
					["coding"] = 0.85,
					["translation"] = 0.8,
					["analysis"] = 0.9,
					["creative"] = 0.75,
					["document"] = 0.8,
					["math"] = 0.95
				}
			},
			new ModelCapability
			{
				Service = "claude",
				Model = "claude-sonnet-4-6",
				Alias = "Claude Sonnet 4.6",
				Scores = new Dictionary<string, double>
				{
					["coding"] = 0.9,
					["translation"] = 0.85,
					["analysis"] = 0.9,
					["creative"] = 0.9,
					["document"] = 0.85,
					["math"] = 0.8
				}
			},
			new ModelCapability
			{
				Service = "claude",
				Model = "claude-opus-4-6",
				Alias = "Claude Opus 4.6",
				Scores = new Dictionary<string, double>
				{
					["coding"] = 0.95,
					["translation"] = 0.9,
					["analysis"] = 0.95,
					["creative"] = 0.95,
					["document"] = 0.9,
					["math"] = 0.85
				}
			},
			new ModelCapability
			{
				Service = "claude",
				Model = "claude-haiku-4-5",
				Alias = "Claude Haiku 4.5",
				Scores = new Dictionary<string, double>
				{
					["coding"] = 0.65,
					["translation"] = 0.7,
					["analysis"] = 0.65,
					["creative"] = 0.6,
					["document"] = 0.6,
					["math"] = 0.6
				}
			}
		};
	}
}
