import { Conversation } from '@/entities/conversation.entity';
import AppResponse from '@/system/filters/response/app-response';
import { SystemLang } from '@/system/lang/system.lang';
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { paginate, PaginateQuery } from 'nestjs-paginate';
import { ILike, Repository } from 'typeorm';
import { CreateMessageDto } from '../messages/dtos/create-message.dto';
import { MessagesEventService } from '../messages/messages-event.service';
import { MessagesService } from '../messages/messages.service';

@Injectable()
export class ConversationsService {
  constructor(
    @InjectRepository(Conversation)
    readonly repo: Repository<Conversation>,
    private event: MessagesEventService,
    private messageService: MessagesService,
  ) {}

  async index(query: PaginateQuery & { current: boolean }) {
    if (query.current) {
      await this.event.sendEvent(
        MessagesEventService.EVENTS.GET_CONVERSATIONS,
        {},
      );

      try {
        await this.event.waitForEvent<Conversation[]>(
          MessagesEventService.LOCAL_EVENTS.RECEIVE_CONVERSATIONS,
        );
      } catch (error) {
        console.log(error);
      }
    }

    const result = await paginate(query, this.repo, {
      sortableColumns: ['created_at', 'name'],
      searchableColumns: ['name'],
      defaultLimit: 10,
      filterableColumns: {
        id: true,
        name: true,
      },
      maxLimit: 100,
      defaultSortBy: [['created_at', 'DESC']],
    });

    return AppResponse.toPagination<Conversation>(result, true, Conversation);
  }

  async getConversation(id: Conversation['id']) {
    const prev = await this.repo.findOne({
      where: { id },
    });

    if (!prev)
      throw new NotFoundException(
        AppResponse.toResponse(null, {
          message: SystemLang.getText('messages', 'not_found'),
        }),
      );

    await this.event.sendEvent(MessagesEventService.EVENTS.GET_CONVERSATION, {
      id,
    });

    try {
      await this.event.waitForEvent<CreateMessageDto[]>(
        MessagesEventService.LOCAL_EVENTS.RECEIVE_CONVERSATION,
      );
    } catch (error) {
      console.log(error);
    }

    const result = await this.repo.findOne({
      where: { id },
    });

    const messages = await this.messageService.repo.find({
      where: { room_id: result.id },
      take: 20,
      order: {
        time_raw: 'DESC',
      },
    });

    result.messages = messages;

    if (!result)
      throw new NotFoundException(
        AppResponse.toResponse(null, {
          message: SystemLang.getText('messages', 'no_data'),
        }),
      );

    return AppResponse.toResponse(result);
  }

  async getConversationsByPrefix() {
    const prefix = (process.env.GROUP_PREFIX || '').trim();

    const conversations = await this.repo.find({
      where: {
        name: ILike(`%${prefix}%`),
      },
    });

    return AppResponse.toResponse(conversations || []);
  }
}
