"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var AdminDriverService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AdminDriverService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("typeorm");
const typeorm_2 = require("@nestjs/typeorm");
const user_entity_1 = require("../../common/vendor/user.entity");
const user_entity_2 = require("../../common/vendor/user.entity");
const driver_entity_1 = require("../../common/driver/driver.entity");
const bcrypt = require("bcrypt");
const driver_review_entity_1 = require("../../common/driverreview/driver-review.entity");
let AdminDriverService = AdminDriverService_1 = class AdminDriverService {
    constructor(userRepository, driverRepository) {
        this.userRepository = userRepository;
        this.driverRepository = driverRepository;
        this.logger = new common_1.Logger(AdminDriverService_1.name);
    }
    async create(CreateDriverDto) {
        const userId = this.generateUserId(CreateDriverDto.name, CreateDriverDto.email);
        const hashedPassword = await this.hashPassword(CreateDriverDto.password);
        const user = this.userRepository.create({
            ...CreateDriverDto,
            userId,
            password: hashedPassword,
        });
        const savedUser = await this.userRepository.save(user);
        const driver = this.driverRepository.create({
            vendorId: CreateDriverDto.vendorId,
            shopId: CreateDriverDto.shopId,
            vehicle_photo: CreateDriverDto.vehicle_photo,
            name_plate: CreateDriverDto.name_plate,
            dl_number: CreateDriverDto.dl_number,
            dl_expiry_date: CreateDriverDto.dl_expiry_date,
            experience: CreateDriverDto.experience,
            services: CreateDriverDto.services,
            documents: CreateDriverDto.documents,
            driverId: CreateDriverDto.driverId,
            vehicle_name: CreateDriverDto.vehicle_name,
            vehicle_color: CreateDriverDto.vehicle_color,
            user: savedUser,
        });
        await this.driverRepository.save(driver);
        return savedUser;
    }
    async findAll(shopId) {
        const result = await this.userRepository
            .createQueryBuilder('user')
            .leftJoinAndSelect('user.driver', 'driver')
            .leftJoinAndMapMany('driver.reviews', driver_review_entity_1.DriverReview, 'reviews', 'reviews.driverId = driver.userId')
            .addSelect('AVG(reviews.rating)', 'driver_avg_rating')
            .where('user.roles LIKE :role', { role: `%${user_entity_2.UserRole.DRIVER}%` })
            .andWhere('driver.shopId = :shopId', { shopId })
            .groupBy('user.id')
            .addGroupBy('driver.id')
            .getRawAndEntities();
        result.entities.forEach((userEntity, idx) => {
            const raw = result.raw[idx];
            const avg = raw?.driver_avg_rating;
            let avgRating = avg !== null && avg !== undefined ? Number(avg) : 0;
            userEntity['avgRating'] = Number(avgRating.toFixed(1));
        });
        return result.entities;
    }
    async findOne(id) {
        const driver = await this.userRepository.findOne({
            where: { id },
            relations: ['driver'],
        });
        if (!driver) {
            throw new common_1.NotFoundException(`Driver with ID ${id} not found`);
        }
        return driver;
    }
    async update(id, updateDriverDto) {
        this.logger.log(`Updating user with ID: ${id}`);
        const user = await this.userRepository.findOne({
            where: { id },
            relations: ['driver'],
        });
        if (!user) {
            this.logger.error(`User with ID ${id} not found`);
            throw new common_1.NotFoundException('User not found');
        }
        this.logger.log('Updating USER fields');
        if (updateDriverDto.name)
            user.name = updateDriverDto.name;
        if (updateDriverDto.lastName)
            user.lastName = updateDriverDto.lastName;
        if (updateDriverDto.dateOfBirth)
            user.dateOfBirth = updateDriverDto.dateOfBirth;
        if (updateDriverDto.nationality)
            user.nationality = updateDriverDto.nationality;
        if (updateDriverDto.preferredLanguage)
            user.preferredLanguage = updateDriverDto.preferredLanguage;
        if (updateDriverDto.gender)
            user.gender = updateDriverDto.gender;
        if (updateDriverDto.status !== undefined)
            user.status = updateDriverDto.status;
        await this.userRepository.save(user);
        this.logger.log(`User updated successfully: ${id}`);
        this.logger.log('Updating DRIVER fields');
        if (!user.driver) {
            this.logger.warn(`Driver NOT FOUND for user ${id}. Skipping driver update.`);
            return this.findOne(id);
        }
        const driver = user.driver;
        if (updateDriverDto.vehicle_photo)
            driver.vehicle_photo = updateDriverDto.vehicle_photo;
        if (updateDriverDto.name_plate)
            driver.name_plate = updateDriverDto.name_plate;
        if (updateDriverDto.services)
            driver.services = updateDriverDto.services;
        if (updateDriverDto.documents)
            driver.documents = updateDriverDto.documents;
        if (updateDriverDto.vehicle_name)
            driver.vehicle_name = updateDriverDto.vehicle_name;
        if (updateDriverDto.vehicle_color)
            driver.vehicle_color = updateDriverDto.vehicle_color;
        if (updateDriverDto.vendorId)
            driver.vendorId = updateDriverDto.vendorId;
        if (updateDriverDto.shopId)
            driver.shopId = updateDriverDto.shopId;
        if (updateDriverDto.dl_number)
            driver.dl_number = updateDriverDto.dl_number;
        if (updateDriverDto.dl_expiry_date)
            driver.dl_expiry_date = updateDriverDto.dl_expiry_date;
        if (updateDriverDto.experience)
            driver.experience = updateDriverDto.experience;
        await this.driverRepository.save(driver);
        this.logger.log(`Driver updated successfully for user ${id}`);
        this.logger.log(`Update process complete for user ${id}`);
        return this.findOne(id);
    }
    async updateUserStatus(userId, status) {
        const user = await this.userRepository.findOne({ where: { id: userId } });
        if (!user) {
            throw new common_1.NotFoundException('User not found');
        }
        user.status = status;
        user.userVerified = (status === "active") ? 1 : 0;
        const res = this.userRepository.save(user);
        return res;
    }
    async remove(id) {
        const result = await this.userRepository.delete(id);
        if (result.affected === 0) {
            throw new common_1.NotFoundException(`Driver with ID ${id} not found`);
        }
    }
    generateUserId(name, email) {
        const timestamp = Date.now();
        const emailInitials = email.slice(0, 2).toUpperCase();
        const year = new Date().getFullYear();
        const userId = `${name.replace(/\s+/g, '').toLowerCase()}${emailInitials}${year}${timestamp}`;
        return userId;
    }
    async hashPassword(password) {
        const salt = await bcrypt.genSalt();
        return await bcrypt.hash(password, salt);
    }
    async findDriverDetail(driverId) {
        const driver = await this.driverRepository.findOne({
            where: { user: { id: driverId } },
            relations: ['user'],
        });
        return driver;
    }
};
exports.AdminDriverService = AdminDriverService;
exports.AdminDriverService = AdminDriverService = AdminDriverService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_2.InjectRepository)(user_entity_1.User)),
    __param(1, (0, typeorm_2.InjectRepository)(driver_entity_1.Driver)),
    __metadata("design:paramtypes", [typeorm_1.Repository,
        typeorm_1.Repository])
], AdminDriverService);
//# sourceMappingURL=admin.driver.service.js.map