import { Injectable, BadRequestException } from '@nestjs/common';
import { AdminService } from '../admin/admin.service';
import { TeachersService } from '../teachers/teachers.service';
import { StudentsService } from '../students/students.service';
import { Role } from '../common/roles/role.enum';
import { UpdateProfileDto } from './dto/update-profile.dto';
import { UpdateNotificationPrefsDto } from './dto/update-notification-prefs.dto';

@Injectable()
export class UsersProfileService {
    constructor(
        private readonly adminService: AdminService,
        private readonly teachersService: TeachersService,
        private readonly studentsService: StudentsService,
    ) {}

    async getProfile(userId: string, role: string) {
        switch (role) {
            case Role.ADMIN:
                return this.adminService.findById(userId);
            case Role.TEACHER:
                return this.teachersService.findOne(userId);
            case Role.STUDENT:
                return this.studentsService.findOne(userId);
            default:
                throw new BadRequestException('Invalid role');
        }
    }

    async updateProfile(userId: string, role: string, dto: UpdateProfileDto) {
        switch (role) {
            case Role.ADMIN:
                return this.adminService.updateProfile(userId, {
                    name: dto.name,
                    phone: dto.phone,
                    photoUrl: dto.photoUrl,
                });
            case Role.TEACHER:
                return this.teachersService.updateSelfProfile(userId, {
                    name: dto.name,
                    phone: dto.phone,
                    photoUrl: dto.photoUrl,
                });
            case Role.STUDENT:
                return this.studentsService.updateSelfProfile(userId, {
                    name: dto.name,
                    phone: dto.phone,
                    profileImageUrl: dto.photoUrl,
                });
            default:
                throw new BadRequestException('Invalid role');
        }
    }

    async updateEmail(userId: string, role: string, newEmail: string) {
        const email = (newEmail || '').trim().toLowerCase();
        if (!email) throw new BadRequestException('Email is required');

        // Cross-collection uniqueness check
        const [adminMatch, teacherMatch, studentMatch] = await Promise.all([
            this.adminService.findByEmail(email),
            this.teachersService.findByEmail(email),
            this.studentsService.findByEmail(email),
        ]);

        // Filter out the current user's own record
        const otherUser = [adminMatch, teacherMatch, studentMatch].find(
            (u) => u && String(u._id) !== userId,
        );
        if (otherUser) throw new BadRequestException('Email already in use');

        switch (role) {
            case Role.ADMIN:
                return this.adminService.updateEmail(userId, email);
            case Role.TEACHER:
                return this.teachersService.updateEmail(userId, email);
            case Role.STUDENT:
                return this.studentsService.updateEmail(userId, email);
            default:
                throw new BadRequestException('Invalid role');
        }
    }

    async updateNotificationPrefs(userId: string, role: string, prefs: UpdateNotificationPrefsDto) {
        switch (role) {
            case Role.ADMIN:
                return this.adminService.updateNotificationPrefs(userId, prefs);
            case Role.TEACHER:
                return this.teachersService.updateNotificationPrefs(userId, prefs);
            case Role.STUDENT:
                return this.studentsService.updateNotificationPrefs(userId, prefs);
            default:
                throw new BadRequestException('Invalid role');
        }
    }
}
