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

export interface IWhatsappAdapterResult {
  result?: IStreamHandleResult;
  error?: IChatError;
  conversationId?: string;
  phoneNumber: string;
  errorChunks?: string[];
  newResponseMessage?: SingleChat;
}

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

  constructor(phoneNumber: string) {
    this.phoneNumber = phoneNumber;
  }

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

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

  async sendErrorProgress(chunk: string): Promise<void> {
    this.logger.log(`WhatsappResponseAdapter.sendErrorProgress: Collecting error progress chunk for ${this.phoneNumber}`);
    this.errorChunks.push(chunk);
  }

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

      this.newResponseMessage = chatHistory.history[chatHistory.history.length - 1];
    }

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

    if (result.responseImage) {
      result.responseImage = result.responseImage;
    }

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

    this.result = result;
  }

  async sendFunctionCall(functionCall: { name: string; arguments: any }): Promise<void> {
    this.logger.log(`WhatsappResponseAdapter.sendFunctionCall: Function call ${functionCall.name} for ${this.phoneNumber}`);
    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(`WhatsappResponseAdapter.endStream: Stream ended for ${this.phoneNumber}`);
  }

  getResult(): IWhatsappAdapterResult {
    if (this.error) {
      return { 
        error: this.error, 
        conversationId: this.conversationId || undefined,
        phoneNumber: this.phoneNumber,
        errorChunks: this.errorChunks.length > 0 ? this.errorChunks : undefined,
        newResponseMessage: this.newResponseMessage,
      };
    }
    return { 
      result: this.result || undefined, 
      conversationId: this.conversationId || undefined,
      phoneNumber: this.phoneNumber,
      errorChunks: this.errorChunks.length > 0 ? this.errorChunks : undefined,
      newResponseMessage: this.newResponseMessage,
    };
  }

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