// feedback/feedback.service.ts
import { Injectable, ForbiddenException, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CourseFeedback } from './course-feedback.entity';
import { Enrollment } from '../enrollments/enrollment.entity';
import { Course } from '../course/course.entity';
import { CreateFeedbackDto } from './dto/create-feedback.dto';
import { UpdateFeedbackDto } from './dto/update-feedback.dto';

@Injectable()
export class FeedbackService {
    constructor(
        @InjectRepository(CourseFeedback) private fbRepo: Repository<CourseFeedback>,
        @InjectRepository(Enrollment) private enrollRepo: Repository<Enrollment>,
        @InjectRepository(Course) private courseRepo: Repository<Course>,
    ) { }

    // private async recalcCourseRating(courseId: number) {
    //     const raw = await this.fbRepo.createQueryBuilder('f')
    //         .select('AVG(f.rating)', 'avg')
    //         .addSelect('COUNT(*)', 'cnt')
    //         .where('f.courseId = :courseId', { courseId })
    //         .andWhere("f.status = 'published'")
    //         .getRawOne<{ avg: string; cnt: string }>();
    //     const avg = raw?.avg ?? '0';
    //     const cnt = raw?.cnt ?? '0';

    //     await this.courseRepo.update(courseId, {
    //         ratingAvg: (avg ?? 0).toString(),
    //         ratingCount: Number(cnt ?? 0),
    //     });
    // }
    private async recalcCourseRating(courseId: number) {
        const raw = await this.fbRepo.createQueryBuilder('f')
            .select('AVG(f.rating)', 'avg')
            .addSelect('COUNT(*)', 'cnt')
            .where('f.courseId = :courseId', { courseId })
            .andWhere("f.status = 'published'")
            .getRawOne<{ avg: string | null; cnt: string | null }>();

        const avgNum = raw?.avg ? Number(raw.avg) : 0;
        const cntNum = raw?.cnt ? Number(raw.cnt) : 0;

        await this.courseRepo.update(courseId, {
            ratingAvg: avgNum.toString(),      // غيّرها إلى string لو العمود نصي عندك
            ratingCount: cntNum,
        });
    }

    async create(userId: number, courseId: number, dto: CreateFeedbackDto) {
        // must be enrolled and active to review
        const active = await this.enrollRepo.findOne({
            where: { user: { id: userId }, course: { id: courseId }, status: 'active' },
        });
        if (!active) throw new ForbiddenException('You must be enrolled to review this course.');

        const exists = await this.fbRepo.findOne({ where: { user: { id: userId }, course: { id: courseId } } });
        if (exists) throw new ForbiddenException('You already reviewed this course.');

        const fb = this.fbRepo.create({
            user: { id: userId } as any,
            course: { id: courseId } as any,
            rating: dto.rating,
            comment: dto.comment,
            status: 'published', // or 'pending' if you want moderation
        });
        await this.fbRepo.save(fb);
        await this.recalcCourseRating(courseId);
        return fb;
    }

    async update(userId: number, courseId: number, id: number, dto: UpdateFeedbackDto, isAdminOrTrainer = false) {
        const fb = await this.fbRepo.findOne({ where: { id, course: { id: courseId } } });
        if (!fb) throw new NotFoundException('Feedback not found');

        if (!isAdminOrTrainer && fb.user.id !== userId) {
            throw new ForbiddenException('You can update only your feedback.');
        }

        if (dto.rating !== undefined) fb.rating = dto.rating;
        if (dto.comment !== undefined) fb.comment = dto.comment;
        if (isAdminOrTrainer && dto.status) fb.status = dto.status;

        await this.fbRepo.save(fb);
        await this.recalcCourseRating(courseId);
        return fb;
    }

    async remove(userId: number, courseId: number, id: number, isAdminOrTrainer = false) {
        const fb = await this.fbRepo.findOne({ where: { id, course: { id: courseId } } });
        if (!fb) return { deleted: false };
        if (!isAdminOrTrainer && fb.user.id !== userId) {
            throw new ForbiddenException('You can delete only your feedback.');
        }
        await this.fbRepo.remove(fb);
        await this.recalcCourseRating(courseId);
        return { deleted: true };
    }

    async listPublic(courseId: number, skip = 0, take = 20) {
        const [items, total] = await this.fbRepo.findAndCount({
            where: { course: { id: courseId }, status: 'published' },
            order: { createdAt: 'DESC' },
            relations: ['user'], // لو مش eager في الكيان
            skip, take,
        });

        const summary = await this.courseRepo.findOne({ where: { id: courseId } });

        return {
            total,
            ratingAvg: summary?.ratingAvg ?? 0,   // أو '0' لو عمود نصي
            ratingCount: summary?.ratingCount ?? 0,
            items: items.map(f => ({
                id: f.id,
                user: { id: f.user.id, email: f.user.email },
                rating: f.rating,
                comment: f.comment,
                createdAt: f.createdAt,
            })),
        };
    }
}
