import { Injectable, Logger } from '@nestjs/common';
import { IChatResponseAdapter, IChatError } from '../interfaces/chat-response-adapter.interface';
import { IStreamHandleResult } from '../interfaces/stream-response.interface';
import { IChat } from '../chat-history.interface';

@Injectable()
export class DirectResponseAdapter implements IChatResponseAdapter {
  private readonly logger = new Logger(DirectResponseAdapter.name);
  private result: IStreamHandleResult | null = null;
  private error: IChatError | null = null;
  private collectedChunks: string[] = [];
  private conversationId: string | null = null;

  async sendError(error: IChatError): Promise<void> {
    this.logger.log(`DirectResponseAdapter.sendError: Error occurred - ${error.message}`);
    this.error = error;
  }

  async sendProgress(chunk: string): Promise<void> {
    this.collectedChunks.push(chunk);
  }

  async sendErrorProgress(chunk: string): Promise<void> {
    this.logger.log(`DirectResponseAdapter.sendErrorProgress: Collecting error progress chunk`);
    this.collectedChunks.push(chunk);
  }

  async sendFinalResponse(result: IStreamHandleResult, chatHistory?: IChat): Promise<void> {
    this.logger.log(`DirectResponseAdapter.sendFinalResponse: Final response type ${result.type}`);
    
    if (chatHistory) {
      this.conversationId = chatHistory._id.toString();
    }

    if (result.responseText === undefined && this.collectedChunks.length > 0) {
      result.responseText = this.collectedChunks.join('');
    }

    if (chatHistory) {
      result.chatHistory = chatHistory as any as IChat;
    }

    this.result = result;
  }

  async sendFunctionCall(functionCall: { name: string; arguments: any }): Promise<void> {
    this.logger.log(`DirectResponseAdapter.sendFunctionCall: Function call ${functionCall.name}`);
    if (!this.result) {
      this.result = {
        type: 'function_call',
        functionCall,
      };
    } else {
      this.result.type = 'function_call';
      this.result.functionCall = functionCall;
    }
  }

  async sendConversationId(conversationId: string): Promise<void> {
    this.conversationId = conversationId;
  }

  async endStream(): Promise<void> {
    this.logger.log('DirectResponseAdapter.endStream: Stream ended');
  }

  getResult(): { result?: IStreamHandleResult; error?: IChatError; conversationId?: string } {
    if (this.error) {
      return { error: this.error, conversationId: this.conversationId || undefined };
    }
    return { result: this.result || undefined, conversationId: this.conversationId || undefined };
  }

  reset(): void {
    this.result = null;
    this.error = null;
    this.collectedChunks = [];
    this.conversationId = null;
  }
}
