import {
  db,
  EnrollmentStatus,
  Lecture,
  Post,
  PostType,
  SectionDto,
  UserProfile,
  VisitType,
} from '@nice/common';

export async function setPostRelation(params: {
  data: Post;
  staff?: UserProfile;
}) {
  const { data, staff } = params;
  const limitedComments = await db.post.findMany({
    where: {
      parentId: data.id,
      type: PostType.POST_COMMENT,
    },
    include: {
      author: true,
    },
    take: 5,
  });
  const commentsCount = await db.post.count({
    where: {
      parentId: data.id,
      type: PostType.POST_COMMENT,
    },
  });
  const readed =
    (await db.visit.count({
      where: {
        postId: data.id,
        type: VisitType.READED,
        visitorId: staff?.id,
      },
    })) > 0;
  const readedCount = await db.visit.count({
    where: {
      postId: data.id,
      type: VisitType.READED,
    },
  });

  Object.assign(data, {
    readed,
    readedCount,
    limitedComments,
    commentsCount,
    // trouble
  });
}
export async function updateParentLectureStats(parentId: string) {
  const ParentStats = await db.post.aggregate({
    where: {
      ancestors: {
        some: {
          ancestorId: parentId,
          descendant: {
            type: PostType.LECTURE,
            deletedAt: null,
          },
        },
      },
    },
    _count: { _all: true },
    _sum: {
      duration: true,
    },
  });
  await db.post.update({
    where: { id: parentId },
    data: {
      //totalLectures: courseStats._count._all,
      //totalDuration: courseStats._sum.duration || 0,
    },
  });
}

// 更新课程评价统计
export async function updateCourseReviewStats(courseId: string) {
  const reviews = await db.visit.findMany({
    where: {
      postId: courseId,
      type: PostType.COURSE_REVIEW,
      deletedAt: null,
    },
    select: { views: true },
  });
  const numberOfReviews = reviews.length;
  const averageRating =
    numberOfReviews > 0
      ? reviews.reduce((sum, review) => sum + review.views, 0) / numberOfReviews
      : 0;

  return db.post.update({
    where: { id: courseId },
    data: {
      // numberOfReviews,
      //averageRating,
    },
  });
}
// 更新课程注册统计
export async function updateCourseEnrollmentStats(courseId: string) {
  const completedEnrollments = await db.enrollment.count({
    where: {
      postId: courseId,
      status: EnrollmentStatus.COMPLETED,
    },
  });
  const totalEnrollments = await db.enrollment.count({
    where: { postId: courseId },
  });
  const completionRate =
    totalEnrollments > 0 ? (completedEnrollments / totalEnrollments) * 100 : 0;
  return db.post.update({
    where: { id: courseId },
    data: {
      // numberOfStudents: totalEnrollments,
      // completionRate,
    },
  });
}

export async function setPostInfo({ data }: { data: Post }) {
  // await db.term
  if (data?.type === PostType.COURSE) {
    const ancestries = await db.postAncestry.findMany({
      where: {
        ancestorId: data.id,
      },
      select: {
        id: true,
        descendant: true,
      },
      orderBy: {
        descendant: {
          order: 'asc',
        },
      },
    });
    const descendants = ancestries.map((ancestry) => ancestry.descendant);
    const sections: SectionDto[] = (
      descendants.filter((descendant) => {
        return (
          descendant.type === PostType.SECTION &&
          descendant.parentId === data.id
        );
      }) as any
    ).map((section) => ({
      ...section,
      lectures: [],
    }));
    const lectures = descendants.filter((descendant) => {
      return (
        descendant.type === PostType.LECTURE &&
        sections.map((section) => section.id).includes(descendant.parentId)
      );
    });

    const lectureCount = lectures?.length || 0;
    sections.forEach((section) => {
      section.lectures = lectures.filter(
        (lecture) => lecture.parentId === section.id,
      ) as any as Lecture[];
    });

    Object.assign(data, { sections, lectureCount });
  }
  if (data?.type === PostType.LECTURE || data?.type === PostType.SECTION) {
    const ancestry = await db.postAncestry.findFirst({
      where: {
        descendantId: data?.id,
        ancestor: {
          type: PostType.COURSE,
        },
      },
      select: {
        ancestor: { select: { id: true } },
      },
    });
    const courseId = ancestry.ancestor.id;
    Object.assign(data, { courseId });
  }
  const students = await db.staff.findMany({
    where: {
      learningPosts: {
        some: {
          id: data.id,
        },
      },
    },
    select: {
      id: true,
    },
  });

  const studentIds = (students || []).map((student) => student?.id);
  Object.assign(data, { studentIds });
}
