import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { PrivateMessage } from './entities/private-message.entity';
import { SendPrivateMessageDto } from './dto/send-private-message.dto';

@Injectable()
export class PrivateChatService {
  constructor(
    @InjectRepository(PrivateMessage)
    private readonly privateMessagesRepository: Repository<PrivateMessage>,
  ) {}

  async send(dto: SendPrivateMessageDto) {
    const message = this.privateMessagesRepository.create({
      ...dto,
      messageType: dto.messageType || 'text',
      status: 'sent',
      isDelivered: false,
      isRead: false,
      isDeleted: false,
    });

    return this.privateMessagesRepository.save(message);
  }

  conversation(userA: string, userB: string, limit = 50) {
    return this.privateMessagesRepository
      .createQueryBuilder('message')
      .where(
        '(message.senderId = :userA AND message.receiverId = :userB) OR (message.senderId = :userB AND message.receiverId = :userA)',
        { userA, userB },
      )
      .andWhere('message.isDeleted = :isDeleted', { isDeleted: false })
      .orderBy('message.createdAt', 'DESC')
      .take(limit)
      .getMany();
  }

  async markDelivered(messageId: string) {
    const message = await this.privateMessagesRepository.findOne({
      where: { id: messageId },
    });

    if (!message) throw new NotFoundException('Message not found');

    message.status = 'delivered';
    message.isDelivered = true;
    message.deliveredAt = new Date();

    return this.privateMessagesRepository.save(message);
  }

  async markRead(messageId: string) {
    const message = await this.privateMessagesRepository.findOne({
      where: { id: messageId },
    });

    if (!message) throw new NotFoundException('Message not found');

    message.status = 'read';
    message.isDelivered = true;
    message.isRead = true;
    message.readAt = new Date();

    return this.privateMessagesRepository.save(message);
  }

  async edit(messageId: string, content: string) {
    const message = await this.privateMessagesRepository.findOne({
      where: { id: messageId },
    });

    if (!message) throw new NotFoundException('Message not found');

    message.content = content;
    message.isEdited = true;

    return this.privateMessagesRepository.save(message);
  }

  async remove(messageId: string) {
    const message = await this.privateMessagesRepository.findOne({
      where: { id: messageId },
    });

    if (!message) throw new NotFoundException('Message not found');

    message.isDeleted = true;
    message.content = '';

    await this.privateMessagesRepository.save(message);
    return { success: true };
  }
}
