import { Logger, Injectable, BadRequestException } from '@nestjs/common';
import { CreateCommentDto } from './dto/create-comment.dto';
import { UpdateCommentDto } from './dto/update-comment.dto';
import { PrismaService } from 'src/prisma/prisma.service';
import { AuthPayload } from 'src/auth/decorators/auth.payload';
import { COMMENT_NOTFOUND, SLOT_NOTFOUND } from 'src/share/eCode';
import { SearchCommentDto } from './dto/search-comment,dto';
import { eUserType } from 'src/common/auth/type';
@Injectable()
export class CommentService {
  private readonly LOG = new Logger(CommentService.name);

  constructor(private prisma: PrismaService) { }
  async find_comment_by_user(id: number, user: AuthPayload) {
    const comment = await this.prisma.comment.findFirst({
      where: {
        id,
        userId: +user.id,
      },
    });

    if (comment) return comment;
    throw new BadRequestException(COMMENT_NOTFOUND);
  }
  async create(createCommentDto: CreateCommentDto, user: AuthPayload) {
    try {
      // check slot
      const userCreate = {};
      if (user.type == eUserType.TENANT) {
        userCreate['tenantId'] = +user.id;
      } else {
        userCreate['userId'] = +user.id;
      }
      const slot = await this.prisma.slot.findFirst({
        where: { id: createCommentDto.slot_id },
      });
      if (!slot) {
        throw new BadRequestException(SLOT_NOTFOUND);
      }
      await this.prisma.$transaction([
        this.prisma.comment.create({
          data: { ...createCommentDto, ...userCreate },
        }),
      ]);
      return true;
    } catch (e) {
      this.LOG.error(e);
      throw e;
    }
  }

  async findAll(
    slot_id: number,
    query: SearchCommentDto,
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    user: AuthPayload = null,
  ) {
    try {
      const { pageSize, pageNumber, sort, search } = query;
      const take = pageSize;
      const skip = (pageNumber - 1) * pageSize;
      const condition = {
        where: { slot_id },
        skip,
        take,
        // orderBy: sort,
        include: {
          tenant: true,
          user: true,
          _count: { select: { likes: true } },
        },
      };
      const [comments, total] = await this.prisma.$transaction([
        this.prisma.comment.findMany(condition),
        this.prisma.comment.count({ where: condition.where }),
      ]);
      return {
        comments: comments?.map((e) => {
          delete e?.user?.password;
          delete e?.user?.username;
          delete e?.tenant?.username;
          delete e?.tenant?.username;
          return {
            ...e,
          };
        }),
        total,
      };
    } catch (error) {
      this.LOG.error(error);
      throw error;
    }
  }

  async findOne(id: number, user: AuthPayload = null) {
    try {
      const comment = await this.prisma.comment.findFirst({
        where: {
          id,
        },
      });

      if (comment) return comment;
      throw new BadRequestException(COMMENT_NOTFOUND);
    } catch (error) {
      this.LOG.error(error);
      throw error;
    }
  }

  async update(
    id: number,
    updateCommentDto: UpdateCommentDto,
    user: AuthPayload,
  ) {
    try {
      await this.find_comment_by_user(id, user);
      await this.prisma.$transaction([
        this.prisma.comment.update({
          where: { id },
          data: {
            content: updateCommentDto.content,
          },
        }),
      ]);
      return `This action updates a #${id} comment`;
    } catch (error) {
      this.LOG.error(error);
      throw error;
    }
  }

  async remove(id: number, user: AuthPayload) {
    try {
      await this.find_comment_by_user(id, user);
      await this.prisma.$transaction([
        this.prisma.comment.deleteMany({
          where: { id },
        }),
      ]);
    } catch (error) {
      this.LOG.error(error);
      throw error;
    }
  }

  async reactComment(id: number, user: AuthPayload = null) {
    try {
      const comment = await this.find_comment_by_user(id, user);
      const like = await this.prisma.like.findFirst({
        where: {
          commentId: comment.id,
          userId: +user.id,
        },
      });
      if (like) {
        await this.prisma.like.delete({ where: { id: +like.id } });
      } else {
        await this.prisma.like.create({
          data: {
            commentId: comment.id,
            userId: +user.id,
          },
        });
      }
      return true;
    } catch (error) {
      this.LOG.error(error);
      throw error;
    }
  }
}
