import { Injectable } from '@nestjs/common';
import { InjectConnection, InjectModel } from '@nestjs/mongoose';
import mongoose, { Model } from 'mongoose';
import { ChatHistory } from '../chat-history.model';
import { CreateConversationDto } from '../chat-history.validation';
import { IFullUser } from 'src/modules/users/users.interface';
import { ChatGptTextService } from 'src/shared/third-party/services/chat-gpt/services/chat-gpt-text.service';
import { CompanyAnalyticsService } from 'src/modules/company-analytics/company-analytics.service';
import { UserAnalyticsService } from 'src/modules/user-analytics/user-analytics.service';
import { LanguageService } from 'src/shared/language/language.service';
// import { selectChatService } from '../utils/getAiModels'; // Moved to AiModelsService
import { ClaudeService } from 'src/shared/third-party/services/claude/claude.service';
import { Subscription } from 'src/modules/subscriptions/subscriptions.model';
import { AiModelsService } from '../../app-config/ai-models/ai-models.service';

@Injectable()
export class BlockedMessageService {
  constructor(
    @InjectModel(ChatHistory.name) private readonly chatHistoryModel: Model<ChatHistory>,
    @InjectConnection() private readonly connection: mongoose.Connection,
    private readonly chatGptTextService: ChatGptTextService,
    private readonly claudeService: ClaudeService,
    private readonly companyAnalyticsService: CompanyAnalyticsService,
    private readonly userAnalyticsService: UserAnalyticsService,
    private readonly languageService: LanguageService,
    @InjectModel(Subscription.name) private readonly subscriptionModel: Model<Subscription>,
    private readonly aiModelsService: AiModelsService,
  ) { }

  // Handle all text messages from this function
  async handleBlockedMessage(
    createChatDto: CreateConversationDto,
    generatedResponse: string | '',
    blockedObject: { success: boolean; reason: string, blockedMessage: { en: string; he: string; } | null },
    user: IFullUser,
    regenarateMessageId: string = '',
    isRegenerate: boolean = false,
    isRetry: boolean = false,
    reasoning: string | null = null
  ) {
    const session = await this.connection.startSession();

    const isHebrew = user.language === 'HB' ? true : false;
    try {
      // start transaction
      session.startTransaction();


      // get model name
      const modelName = await this.subscriptionModel.findOne({ user: user._id }).select('aiModel').lean().exec();

      const model = modelName?.aiModel || 'gpt-3.5';

      let chatHistory: any;

      // check if the conversation is old or not
      let isNewConversation = false;

      // Check if conversationId exists
      if (createChatDto?.conversationId) {
        const existingChatHistory = await this.chatHistoryModel.findById(
          createChatDto.conversationId,
        );

        // If conversation exists, then update the chat history
        if (existingChatHistory) {
          if (!isRegenerate && !regenarateMessageId) {
            existingChatHistory.history.push({
              ...createChatDto.chat,
              role: 'user',
            });
          }

          chatHistory = existingChatHistory;
        } else {
          isNewConversation = true;
          // If conversation doesn't exist, then create a new chat history and save it
          const newChatHistory = await this.generateNewChatHistory(
            createChatDto?.chat?.content,
            user._id,
          );

          newChatHistory.history.push({
            ...createChatDto.chat,
            role: 'user',
          });

          chatHistory = newChatHistory;
        }
      } else {
        isNewConversation = true;
        // If conversationId doesn't exist, then create a new chat history and save it
        const newChatHistory = await this.generateNewChatHistory(
          createChatDto?.chat?.content,
          user._id,
        );
        newChatHistory.history.push({
          ...createChatDto.chat,
          role: 'user',
        });

        chatHistory = newChatHistory;
      }
      // HTML tags for bold text
      const boldStart =
        '<b style="color:red; font-weight:bold; font-size:1.1em;">';
      const boldEnd = '</b>';

      let content = isHebrew
        ? (blockedObject?.blockedMessage?.he || `${boldStart}תוכן התשובה נחסם על ידי הסנן שלנו. אנא נסה שוב עם הודעה אחרת [
מדיניות החסימה שלנו](https://terms.binaplus.co.il)${boldEnd}`)
        : (blockedObject?.blockedMessage?.en || `${boldStart}The content was blocked by our filter. Please try again with a different message [Our Blocking Policy](https://terms.binaplus.co.il/)${boldEnd}`);

      // if there exists a response which was blocked half way
      if (generatedResponse) {
        content = isHebrew
          ? `‏המשך ההודעה נחסמה על ידי הסנן, אנא נסה שוב [
מדיניות החסימה שלנו](https://terms.binaplus.co.il) `
          : `The rest of the content was blocked by our filter. Please try again with a different message [Our Blocking Policy](https://terms.binaplus.co.il/)`;

        // content = `${generatedResponse}\n\n\n${boldStart}${content}${boldEnd}`;

        const contentWithBold = `${boldStart}${content}${boldEnd}`;

        const blockedContent = isHebrew ? (blockedObject?.blockedMessage?.he ? content : contentWithBold) : (blockedObject?.blockedMessage?.en ? content : contentWithBold);

        content = `${generatedResponse}\n\n\n${blockedContent}`;

      }

      const dataToAdd: any = {
        _id: new mongoose.Types.ObjectId(),
        role: 'system',
        type: 'text',
        model: model,
        content: content,
        blockedReason: [blockedObject.reason],
        isRetryAllowed: !isRetry,
      };

      if (reasoning) {
        dataToAdd.metadata = {
          reasoning: reasoning
        };
      }

      if (isRegenerate && regenarateMessageId) {
        // push to parts (if it's not the first message)
        const messageItem = chatHistory.history.find(
          (message: any) => message._id.toString() === regenarateMessageId,
        );

        if (isRetry) {
          messageItem.isRetryAllowed = false;
        }

        const parts = messageItem?.parts || [];
        parts.push(dataToAdd);
      } else {
        chatHistory.history.push(dataToAdd);
      }

      if (isNewConversation) {
        chatHistory.title = isHebrew ? `שיחה חדשה` : `New Conversation`;

        await this.chatHistoryModel
          .updateMany(
            { user: user._id, isNewConversation: { $ne: false } },
            { isNewConversation: false },
          )
          .exec();
      }

      await chatHistory.save({ session });

      // Handle Analytics
      await this.companyAnalyticsService.incrementAnalytics(
        'messageBlocked',
        session,
      );

      // Handle Analytics
      await this.userAnalyticsService.incrementAnalytics(
        'messageBlocked',
        user._id,
        session,
      );

      await session.commitTransaction();
      session.endSession();

      // returning the newly added bad response
      const index = chatHistory.history.findIndex(
        (item: any) => item._id === dataToAdd._id,
      );
      return {
        newResponse: chatHistory.history[index],
        chatHistory,
        isNewConversation,
      };
    } catch (error) {
      await session.abortTransaction();
      session.endSession();
      throw error;
    }
  }

  //   Generate new chat history if conversationId doesn't exist
  private async generateNewChatHistory(title: string, userId: string) {
    const newChatHistory = new this.chatHistoryModel({
      user: userId,
      title: title || 'New Conversation',
    });
    return newChatHistory;
  }
}
