import {
  IsString,
  IsOptional,
  IsUUID,
  IsBoolean,
  IsInt,
  Min,
  Max,
  MaxLength,
} from 'class-validator';
import { Type } from 'class-transformer';

interface CommentEntity {
  id: string;
  content: string;
  articleId?: string;
  liveBlogId?: string;
  parentId?: string;
  userId: string;
  likeCount: number;
  dislikeCount: number;
  isVisible: boolean;
  createdAt: Date;
  updatedAt: Date;
  user?: {
    id: string;
    username: string;
  };
  replies?: CommentEntity[];
}

export class CreateCommentDto {
  @IsString()
  @MaxLength(5000)
  content: string;

  @IsUUID()
  @IsOptional()
  articleId?: string;

  @IsUUID()
  @IsOptional()
  liveBlogId?: string;

  @IsUUID()
  @IsOptional()
  parentId?: string;
}

export class UpdateCommentDto {
  @IsString()
  @MaxLength(5000)
  @IsOptional()
  content?: string;

  @IsBoolean()
  @IsOptional()
  isVisible?: boolean;
}

export class CommentResponseDto {
  id: string;
  content: string;
  articleId?: string;
  liveBlogId?: string;
  parentId?: string;
  userId: string;
  likeCount: number;
  dislikeCount: number;
  isVisible: boolean;
  createdAt: Date;
  updatedAt: Date;
  user: {
    id: string;
    username: string;
  };
  replies?: CommentResponseDto[];

  constructor(comment: CommentEntity) {
    this.id = comment.id;
    this.content = comment.content;
    this.articleId = comment.articleId;
    this.liveBlogId = comment.liveBlogId;
    this.parentId = comment.parentId;
    this.userId = comment.userId;
    this.likeCount = comment.likeCount;
    this.dislikeCount = comment.dislikeCount;
    this.isVisible = comment.isVisible;
    this.createdAt = comment.createdAt;
    this.updatedAt = comment.updatedAt;

    if (comment.user) {
      this.user = {
        id: comment.user.id,
        username: comment.user.username,
      };
    }

    if (comment.replies) {
      this.replies = comment.replies.map(
        (reply) => new CommentResponseDto(reply),
      );
    }
  }
}

export class FindCommentsDto {
  @IsUUID()
  @IsOptional()
  articleId?: string;

  @IsUUID()
  @IsOptional()
  liveBlogId?: string;

  @IsUUID()
  @IsOptional()
  parentId?: string;

  @IsInt()
  @Min(1)
  @IsOptional()
  @Type(() => Number)
  page?: number = 1;

  @IsInt()
  @Min(1)
  @Max(100)
  @IsOptional()
  @Type(() => Number)
  limit?: number = 20;
}

export class CreateReactionDto {
  @IsString()
  type: 'like' | 'dislike';

  @IsUUID()
  @IsOptional()
  articleId?: string;

  @IsUUID()
  @IsOptional()
  liveBlogId?: string;

  @IsUUID()
  @IsOptional()
  commentId?: string;
}
