import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, ItemView, WorkspaceLeaf } from 'obsidian';
import { EventBus } from './src/utils/EventBus';
import { GraphView, GRAPH_VIEW_TYPE } from './src/views/GraphView';
import { ChatView, CHAT_VIEW_TYPE } from './src/views/ChatView';

import 'src/css/styles.css'; // Путь к твоему новому CSS файлу

// ----------------------------------------------- Settings ---------------------------------------------------------------

interface LLMAgentSettings {
	apiBaseUrl: string;
	systemPrompt: string;
	defaultModel: string;
	promptsFolder: string; // Новое поле
	enableFileReferences: boolean; // Новое поле
	enablePromptReferences: boolean; // Новое поле
	excludedFolders: string[]; // Новое поле: Список папок для исключения из автокомплита
}

const DEFAULT_SETTINGS: LLMAgentSettings = {
	apiBaseUrl: 'http://localhost:5000/api',
	systemPrompt: 'Ты полезный ИИ ассистент.',
	defaultModel: 'gemini-2.5-flash',
	promptsFolder: 'prompts', // Папка с промптами по умолчанию
	enableFileReferences: true,
	enablePromptReferences: true,
	excludedFolders: ['templates'] // Папка "templates" по умолчанию исключена
};

// ----------------------------------------------- Main Plugin Class ---------------------------------------------------------------

export default class LLMAgentPlugin extends Plugin {
	settings: LLMAgentSettings;
	eventBus: EventBus;

	async onload() {
		await this.loadSettings();

		this.eventBus = new EventBus();

		// Регистрируем кастомные views
		this.registerView(GRAPH_VIEW_TYPE, (leaf) => new GraphView(leaf, this));
		this.registerView(CHAT_VIEW_TYPE, (leaf) => new ChatView(leaf, this));

		// Добавляем команды
		this.addCommand({
			id: 'open-llm-agent-graph',
			name: 'Открыть граф диалогов LLM Agent',
			callback: () => this.activateGraphView()
		});

		this.addCommand({
			id: 'open-llm-agent-chat',
			name: 'Открыть чат LLM Agent',
			callback: () => this.activateChatView()
		});

		this.addCommand({
			id: 'new-llm-agent-chat',
			name: 'Новый чат LLM Agent',
			callback: () => this.handleNewChat()
		});

		// Добавляем иконку в ribbon
		this.addRibbonIcon('brain-circuit', 'LLM Agent', () => {
			this.activateGraphView();
			this.activateChatView();
		});

		console.log('LLM Agent plugin загружен');

		// This adds a settings tab so the user can configure various aspects of the plugin
		this.addSettingTab(new SampleSettingTab(this.app, this));
	}

	onunload() {
		console.log('LLM Agent plugin выгружен');
	}

	// ----------------------------------------------- Settings Management ---------------------------------------------------------------

	async loadSettings() {
		this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
	}

	async saveSettings() {
		await this.saveData(this.settings);
	}

	// ----------------------------------------------- View Management ---------------------------------------------------------------

	async activateGraphView() {
		const existingLeaf = this.app.workspace.getLeavesOfType(GRAPH_VIEW_TYPE)[0];
		if (existingLeaf) {
			this.app.workspace.revealLeaf(existingLeaf);
		} else {
			await this.app.workspace.getLeaf('tab').setViewState({
				type: GRAPH_VIEW_TYPE,
				active: true
			});
		}
	}

	async activateChatView() {
		const existingLeaf = this.app.workspace.getLeavesOfType(CHAT_VIEW_TYPE)[0];
		if (existingLeaf) {
			this.app.workspace.revealLeaf(existingLeaf);
		} else {
			const rightLeaf = this.app.workspace.getRightLeaf(false);
			if (rightLeaf) {
				await rightLeaf.setViewState({
					type: CHAT_VIEW_TYPE,
					active: true
				});
			}
		}
	}

	// ----------------------------------------------- Event Handlers ---------------------------------------------------------------

	handleNewChat() {
		this.eventBus.emit('new-chat');
	}
}

// ----------------------------------------------- Sample Setting Tab ---------------------------------------------------------------

class SampleSettingTab extends PluginSettingTab {
	plugin: LLMAgentPlugin;

	constructor(app: App, plugin: LLMAgentPlugin) {
		super(app, plugin);
		this.plugin = plugin;
	}

	display(): void {
		const { containerEl } = this;

		containerEl.empty();

		new Setting(containerEl)
			.setName('API Base URL')
			.setDesc('Базовый URL для API LLM Agent')
			.addText((text) =>
				text
					.setPlaceholder('Введите URL')
					.setValue(this.plugin.settings.apiBaseUrl)
					.onChange(async (value) => {
						this.plugin.settings.apiBaseUrl = value;
						await this.plugin.saveSettings();
					})
			);

		// Новое поле для системного промпта
		new Setting(containerEl)
			.setName('Системный промпт')
			.setDesc('Этот промпт будет отправляться LLM перед каждым диалогом.')
			.addTextArea((text) =>
				text
					.setPlaceholder('Ты полезный ИИ ассистент.')
					.setValue(this.plugin.settings.systemPrompt)
					.onChange(async (value) => {
						this.plugin.settings.systemPrompt = value;
						await this.plugin.saveSettings();
					})
			);

		// Новое поле для папки промптов
		new Setting(containerEl)
			.setName('Папка с промптами')
			.setDesc('Путь к папке, содержащей промпты для команд #/##')
			.addText((text) =>
				text
					.setPlaceholder('prompts')
					.setValue(this.plugin.settings.promptsFolder)
					.onChange(async (value) => {
						this.plugin.settings.promptsFolder = value;
						await this.plugin.saveSettings();
					})
			);

		// Настройки ссылок на файлы
		new Setting(containerEl)
			.setName('Включить ссылки на файлы')
			.setDesc('Разрешить использование @/@@ ссылок на файлы в хранилище')
			.addToggle((toggle) =>
				toggle.setValue(this.plugin.settings.enableFileReferences).onChange(async (value) => {
					this.plugin.settings.enableFileReferences = value;
					await this.plugin.saveSettings();
				})
			);

		// Настройки ссылок на промпты
		new Setting(containerEl)
			.setName('Включить ссылки на промпты')
			.setDesc('Разрешить использование #/## ссылок на промпты')
			.addToggle((toggle) =>
				toggle.setValue(this.plugin.settings.enablePromptReferences).onChange(async (value) => {
					this.plugin.settings.enablePromptReferences = value;
					await this.plugin.saveSettings();
				})
			);

		// Новое поле для настройки исключенных папок
		new Setting(containerEl)
			.setName('Исключенные папки для ссылок')
			.setDesc('Список относительных путей к папкам, файлы из которых не будут предлагаться в автодополнении ссылок (@/@@).')
			.addToggle((toggle) =>
				toggle.setValue(this.plugin.settings.enableFileReferences).onChange(async (value) => {
					this.plugin.settings.enableFileReferences = value;
					await this.plugin.saveSettings();
				})
			);

		// Динамический список исключенных папок
		this.plugin.settings.excludedFolders.forEach((folder, index) => {
			new Setting(containerEl)
				.setClass('llm-agent-excluded-folder-item') // Добавляем класс для стилизации
				.addText((text) => {
					text.setPlaceholder('Путь к папке (например, templates/)' + index)
						.setValue(folder)
						.onChange(async (value) => {
							this.plugin.settings.excludedFolders[index] = value;
							await this.plugin.saveSettings();
							// Очищаем кэш автокомплита при изменении настроек
							this.plugin.eventBus.emit('settings-changed');
						});
				})
				.addExtraButton((button) => {
					button
						.setIcon('x')
						.setTooltip('Удалить папку')
						.onClick(async () => {
							this.plugin.settings.excludedFolders.splice(index, 1);
							await this.plugin.saveSettings();
							this.display(); // Перерисовать настройки для обновления списка
							// Очищаем кэш автокомплита при изменении настроек
							this.plugin.eventBus.emit('settings-changed');
						});
				});
		});

		new Setting(containerEl).addButton((button) => {
			button
				.setButtonText('Добавить папку')
				.setIcon('plus')
				.onClick(async () => {
					this.plugin.settings.excludedFolders.push(''); // Добавляем пустое поле
					await this.plugin.saveSettings();
					this.display(); // Перерисовать настройки для обновления списка
				});
		});
	}
}
