/*
 * Управляет и отображает историю графов чата. Предоставляет функционал для выбора
 * прошлых разговоров, начала новых чатов и удаления записей графов.
 */

import LLMAgentPlugin from 'main';
import { EventBus } from '../utils/EventBus';
import { Dialog } from 'src/utils/Dialog';

export class HistoryPanel {
	container: HTMLElement;
	props: {
		graphs: any[];
		eventBus: EventBus;
	};
	plugin: LLMAgentPlugin;
	graphs: any[];
	newChatButton: HTMLButtonElement;
	clearAllButton: HTMLButtonElement;
	chatList: HTMLElement;
	contextMenu: HTMLElement;
	deleteButton: HTMLButtonElement;
	renameButton: HTMLButtonElement;
	contextMenuGraphId: string | null;
	currentPage: number;
	itemsPerPage: number;
	paginationContainer: HTMLElement;

	constructor(
		container: HTMLElement,
		props: {
			graphs: any[];
			eventBus: EventBus;
		},
		plugin: LLMAgentPlugin
	) {
		this.container = container;
		this.props = props;
		this.plugin = plugin;
		this.graphs = props.graphs || [];
		this.currentPage = 1;
		this.itemsPerPage = 40;

		this.init();
	}

	init(): void {
		this.container.innerHTML = `
            <div class="llm-agent-history-panel">
                <div class="history-header">
                    <h3>История диалогов</h3>
                    <div class="history-header-buttons">
                        <button id="new-chat-button" class="new-chat-button">+ Новый чат</button>
                        <button id="clear-all-button" class="clear-all-button">Очистить чаты</button>
                    </div>
                </div>
                <div class="chat-list" id="chat-list"></div>
                <div class="pagination-container" id="pagination-container"></div>
                <div class="menu" id="context-menu" style="display: none;">
                    <button id="rename-graph-button">Переименовать</button>
                    <button id="delete-graph-button">Удалить</button>
                </div>
            </div>
        `;

		this.newChatButton = this.container.querySelector('#new-chat-button') as HTMLButtonElement;
		this.clearAllButton = this.container.querySelector('#clear-all-button') as HTMLButtonElement; // ДОБАВЛЕНО
		this.chatList = this.container.querySelector('#chat-list') as HTMLElement;
		this.paginationContainer = this.container.querySelector('#pagination-container') as HTMLElement; // ДОБАВЛЕНО
		this.contextMenu = this.container.querySelector('#context-menu') as HTMLElement;
		this.renameButton = this.container.querySelector('#rename-graph-button') as HTMLButtonElement; // ДОБАВЛЕНО
		this.deleteButton = this.container.querySelector('#delete-graph-button') as HTMLButtonElement;

		this.setupEventListeners();
		this.renderGraphs();
	}

	setupEventListeners(): void {
		this.newChatButton.addEventListener('click', () => {
			this.props.eventBus.emit('new-chat');
		});

		this.clearAllButton.addEventListener('click', () => {
			this.handleClearAllChats();
		});

		this.renameButton.addEventListener('click', () => {
			if (this.contextMenuGraphId) {
				this.handleRenameGraph(this.contextMenuGraphId);
			}
		});

		this.deleteButton.addEventListener('click', () => {
			if (this.contextMenuGraphId) {
				this.handleDeleteGraph(this.contextMenuGraphId);
			}
		});

		// Закрытие контекстного меню при клике вне его
		document.addEventListener('click', (e) => {
			if (!this.contextMenu.contains(e.target as Node)) {
				this.contextMenu.style.display = 'none';
			}
		});
	}

	renderGraphs(): void {
		const startIndex = (this.currentPage - 1) * this.itemsPerPage;
		const endIndex = startIndex + this.itemsPerPage;
		const graphsToShow = this.graphs.slice(startIndex, endIndex);

		this.chatList.innerHTML = graphsToShow
			.map((graph) => {
				const titleClass = graph.title_generated ? 'graph-title-generated' : 'graph-title-pending';
				const displayTitle = graph.title || graph.first_message || `Граф ${graph.id}`;

				return `
                <div class="chat-list-item" data-graph-id="${graph.id}">
                    <div class="chat-item-content">
                        <div class="chat-item-text">
                            <span class="truncate ${titleClass}">
                                ${displayTitle}
                            </span>
                        </div>
                        <div class="chat-item-actions">
                            <button class="chat-item-options-button" data-graph-id="${graph.id}">
                                ⋮
                            </button>
                        </div>
                    </div>
                </div>
            `;
			})
			.join('');

		// Добавляем обработчики событий
		this.chatList.querySelectorAll('.chat-list-item').forEach((item) => {
			item.addEventListener('click', (e) => {
				if (!(e.target as HTMLElement).classList.contains('chat-item-options-button')) {
					const graphId = (item as HTMLElement).dataset.graphId;
					if (graphId) {
						this.props.eventBus.emit('graph-selected', { graphId: graphId, currentNode: null });
					}
				}
			});
		});

		this.chatList.querySelectorAll('.chat-item-options-button').forEach((button) => {
			button.addEventListener('click', (e) => {
				e.stopPropagation();
				this.showContextMenu(e, (button as HTMLElement).dataset.graphId || '');
			});
		});

		this.renderPagination();
	}

	renderPagination(): void {
		const totalPages = Math.ceil(this.graphs.length / this.itemsPerPage);

		if (totalPages <= 1) {
			this.paginationContainer.innerHTML = '';
			return;
		}

		let paginationHTML = '<div class="pagination-buttons">';

		// Кнопка "Предыдущая"
		if (this.currentPage > 1) {
			paginationHTML += `<button class="pagination-button" data-page="${this.currentPage - 1}">←</button>`;
		}

		// Номера страниц
		const maxVisiblePages = 5;
		let startPage = Math.max(1, this.currentPage - Math.floor(maxVisiblePages / 2));
		let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);

		if (endPage - startPage < maxVisiblePages - 1) {
			startPage = Math.max(1, endPage - maxVisiblePages + 1);
		}

		if (startPage > 1) {
			paginationHTML += `<button class="pagination-button" data-page="1">1</button>`;
			if (startPage > 2) {
				paginationHTML += `<span class="pagination-ellipsis">...</span>`;
			}
		}

		for (let i = startPage; i <= endPage; i++) {
			const activeClass = i === this.currentPage ? 'active' : '';
			paginationHTML += `<button class="pagination-button ${activeClass}" data-page="${i}">${i}</button>`;
		}

		if (endPage < totalPages) {
			if (endPage < totalPages - 1) {
				paginationHTML += `<span class="pagination-ellipsis">...</span>`;
			}
			paginationHTML += `<button class="pagination-button" data-page="${totalPages}">${totalPages}</button>`;
		}

		// Кнопка "Следующая"
		if (this.currentPage < totalPages) {
			paginationHTML += `<button class="pagination-button" data-page="${this.currentPage + 1}">→</button>`;
		}

		paginationHTML += '</div>';
		this.paginationContainer.innerHTML = paginationHTML;

		// Обработчики для кнопок пагинации
		this.paginationContainer.querySelectorAll('.pagination-button').forEach((button) => {
			button.addEventListener('click', (e) => {
				const page = parseInt((e.target as HTMLElement).dataset.page || '1');
				this.currentPage = page;
				this.renderGraphs();
			});
		});
	}

	showContextMenu(event: Event, graphId: string): void {
		event.stopPropagation();
		this.contextMenuGraphId = graphId;

		const buttonElement = event.target as HTMLElement;
		const rect = buttonElement.getBoundingClientRect();

		const workspaceLeafContent = buttonElement.closest('.workspace-leaf-content') as HTMLElement;

		let relativeContainerRect = { left: 0, top: 0 };
		if (workspaceLeafContent) {
			relativeContainerRect = workspaceLeafContent.getBoundingClientRect();
		} else {
			// Если .workspace-leaf-content не найден, используем container как запасной вариант
			relativeContainerRect = this.container.getBoundingClientRect();
		}

		this.contextMenu.style.display = 'flex';
		this.contextMenu.style.left = `${rect.left - relativeContainerRect.left}px`;
		this.contextMenu.style.top = `${rect.bottom - relativeContainerRect.top + 4}px`;
	}

	async handleRenameGraph(graphId: string): Promise<void> {
		try {
			const graph = this.graphs.find((g) => g.id === graphId);
			if (!graph) return;

			const currentTitle = graph.title || graph.first_message || '';

			// Создаём простой промпт для ввода нового названия
			const newTitle = await Dialog.prompt(this.plugin.app, 'Введите новое название:', currentTitle);

			if (newTitle === null || newTitle.trim() === '') {
				return; // Пользователь отменил или ввёл пустое название
			}

			const response = await fetch(`http://localhost:5000/api/graphs/${graphId}/rename`, {
				method: 'PATCH',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify({ title: newTitle.trim() })
			});

			if (!response.ok) {
				throw new Error(`HTTP ошибка! статус: ${response.status}`);
			}

			// Обновляем локальный список графов
			const graphIndex = this.graphs.findIndex((g) => g.id === graphId);
			if (graphIndex !== -1) {
				this.graphs[graphIndex].title = newTitle.trim();
				this.graphs[graphIndex].title_generated = true;
			}

			this.renderGraphs();
			this.contextMenu.style.display = 'none';
		} catch (error) {
			console.error('Ошибка переименования графа:', error);
		}
	}

	async handleClearAllChats(): Promise<void> {
		try {
			const confirmed = confirm('Вы уверены, что хотите удалить все чаты? Это действие нельзя отменить.');

			if (!confirmed) {
				return;
			}

			const response = await fetch(`http://localhost:5000/api/graphs`, {
				method: 'DELETE'
			});

			if (!response.ok) {
				throw new Error(`HTTP ошибка! статус: ${response.status}`);
			}

			// Очищаем список графов
			this.graphs = [];
			this.currentPage = 1;
			this.renderGraphs();

			// Уведомляем об очистке
			this.props.eventBus.emit('all-chats-cleared');
		} catch (error) {
			console.error('Ошибка очистки всех чатов:', error);
		}
	}

	async handleDeleteGraph(graphId: string): Promise<void> {
		try {
			const response = await fetch(`http://localhost:5000/api/graphs/${graphId}`, {
				method: 'DELETE'
			});

			if (!response.ok) {
				throw new Error(`HTTP ошибка! статус: ${response.status}`);
			}

			// Обновляем список графов
			this.graphs = this.graphs.filter((graph) => graph.id !== graphId);

			// Корректируем текущую страницу если нужно
			const totalPages = Math.ceil(this.graphs.length / this.itemsPerPage);
			if (this.currentPage > totalPages && totalPages > 0) {
				this.currentPage = totalPages;
			}

			this.renderGraphs();
			this.contextMenu.style.display = 'none';
		} catch (error) {
			console.error('Ошибка удаления графа:', error);
		}
	}

	updateGraphs(newGraphs: any[]): void {
		this.graphs = newGraphs;
		this.currentPage = 1;
		this.renderGraphs();
	}

	destroy(): void {
		this.container.innerHTML = '';
	}
}
