/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import { CancellationToken } from '../../../../../../base/common/cancellation.js';
import { Event } from '../../../../../../base/common/event.js';
import { ResourceMap } from '../../../../../../base/common/map.js';
import { IObservable, observableValue } from '../../../../../../base/common/observable.js';
import { URI } from '../../../../../../base/common/uri.js';
import { IChatModel, IChatRequestModel, IChatRequestVariableData, ISerializableChatData } from '../../../common/model/chatModel.js';
import { IParsedChatRequest } from '../../../common/requestParser/chatParserTypes.js';
import { ChatRequestQueueKind, ChatSendResult, IChatCompleteResponse, IChatDetail, IChatModelReference, IChatProgress, IChatProviderInfo, IChatSendRequestOptions, IChatService, IChatSessionContext, IChatSessionStartOptions, IChatUserActionEvent } from '../../../common/chatService/chatService.js';
import { ChatAgentLocation } from '../../../common/constants.js';

export class MockChatService implements IChatService {
	chatModels: IObservable<Iterable<IChatModel>> = observableValue('chatModels', []);
	requestInProgressObs = observableValue('name', false);
	_serviceBrand: undefined;
	editingSessions = [];
	transferredSessionResource: URI | undefined;
	readonly onDidSubmitRequest: Event<{ readonly chatSessionResource: URI; readonly message?: IParsedChatRequest }> = Event.None;
	readonly onDidCreateModel: Event<IChatModel> = Event.None;

	private sessions = new ResourceMap<IChatModel>();

	setSaveModelsEnabled(enabled: boolean): void {

	}
	isEnabled(location: ChatAgentLocation): boolean {
		throw new Error('Method not implemented.');
	}
	hasSessions(): boolean {
		throw new Error('Method not implemented.');
	}
	getProviderInfos(): IChatProviderInfo[] {
		throw new Error('Method not implemented.');
	}
	startNewLocalSession(location: ChatAgentLocation, options?: IChatSessionStartOptions): IChatModelReference {
		throw new Error('Method not implemented.');
	}
	addSession(session: IChatModel): void {
		this.sessions.set(session.sessionResource, session);
	}
	getSession(sessionResource: URI): IChatModel | undefined {
		// eslint-disable-next-line local/code-no-dangerous-type-assertions
		return this.sessions.get(sessionResource) ?? {} as IChatModel;
	}
	getLatestRequest(): IChatRequestModel | undefined {
		return undefined;
	}
	async acquireOrRestoreSession(sessionResource: URI): Promise<IChatModelReference | undefined> {
		throw new Error('Method not implemented.');
	}
	getSessionTitle(sessionResource: URI): string | undefined {
		throw new Error('Method not implemented.');
	}
	loadSessionFromData(data: ISerializableChatData): IChatModelReference {
		throw new Error('Method not implemented.');
	}
	acquireOrLoadSession(resource: URI, position: ChatAgentLocation, token: CancellationToken): Promise<IChatModelReference | undefined> {
		throw new Error('Method not implemented.');
	}
	acquireExistingSession(sessionResource: URI): IChatModelReference | undefined {
		return undefined;
	}
	setSessionTitle(sessionResource: URI, title: string): void {
		throw new Error('Method not implemented.');
	}
	appendProgress(request: IChatRequestModel, progress: IChatProgress): void {

	}
	processPendingRequests(sessionResource: URI): void {

	}
	/**
	 * Returns whether the request was accepted.
	 */
	sendRequest(sessionResource: URI, message: string): Promise<ChatSendResult> {
		throw new Error('Method not implemented.');
	}
	resendRequest(request: IChatRequestModel, options?: IChatSendRequestOptions | undefined): Promise<void> {
		throw new Error('Method not implemented.');
	}
	adoptRequest(sessionResource: URI, request: IChatRequestModel): Promise<void> {
		throw new Error('Method not implemented.');
	}
	removeRequest(sessionResource: URI, requestId: string): Promise<void> {
		throw new Error('Method not implemented.');
	}
	cancelCurrentRequestForSession(sessionResource: URI, source?: string): void {
		throw new Error('Method not implemented.');
	}
	setYieldRequested(sessionResource: URI): void {
		throw new Error('Method not implemented.');
	}
	removePendingRequest(sessionResource: URI, requestId: string): void {
		throw new Error('Method not implemented.');
	}
	setPendingRequests(sessionResource: URI, requests: readonly { requestId: string; kind: ChatRequestQueueKind }[]): void {
		throw new Error('Method not implemented.');
	}
	addCompleteRequest(sessionResource: URI, message: IParsedChatRequest | string, variableData: IChatRequestVariableData | undefined, attempt: number | undefined, response: IChatCompleteResponse): void {
		throw new Error('Method not implemented.');
	}
	async getLocalSessionHistory(): Promise<IChatDetail[]> {
		throw new Error('Method not implemented.');
	}
	async clearAllHistoryEntries() {
		throw new Error('Method not implemented.');
	}
	async removeHistoryEntry(resource: URI) {
		throw new Error('Method not implemented.');
	}

	readonly onDidPerformUserAction: Event<IChatUserActionEvent> = undefined!;
	notifyUserAction(event: IChatUserActionEvent): void {
		throw new Error('Method not implemented.');
	}
	readonly onDidReceiveQuestionCarouselAnswer: Event<{ requestId: string; resolveId: string; answers: Record<string, unknown> | undefined }> = undefined!;
	notifyQuestionCarouselAnswer(requestId: string, resolveId: string, answers: Record<string, unknown> | undefined): void {
		throw new Error('Method not implemented.');
	}
	readonly onDidDisposeSession: Event<{ sessionResource: URI[]; reason: 'cleared' }> = undefined!;

	async transferChatSession(transferredSessionResource: URI, toWorkspace: URI): Promise<void> {
		throw new Error('Method not implemented.');
	}

	setChatSessionTitle(sessionResource: URI, title: string): void {
		throw new Error('Method not implemented.');
	}

	isEditingLocation(location: ChatAgentLocation): boolean {
		throw new Error('Method not implemented.');
	}

	getChatStorageFolder(): URI {
		throw new Error('Method not implemented.');
	}

	logChatIndex(): void {
		throw new Error('Method not implemented.');
	}

	activateDefaultAgent(location: ChatAgentLocation): Promise<void> {
		throw new Error('Method not implemented.');
	}

	getChatSessionFromInternalUri(sessionResource: URI): IChatSessionContext | undefined {
		throw new Error('Method not implemented.');
	}

	async getLiveSessionItems(): Promise<IChatDetail[]> {
		throw new Error('Method not implemented.');
	}
	getHistorySessionItems(): Promise<IChatDetail[]> {
		throw new Error('Method not implemented.');
	}

	waitForModelDisposals(): Promise<void> {
		throw new Error('Method not implemented.');
	}
	getMetadataForSession(sessionResource: URI): Promise<IChatDetail | undefined> {
		throw new Error('Method not implemented.');
	}
}
