import { Injectable, NotFoundException, Logger } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { UpdateUserDto, ApproveUserDto } from './dto';
import { Role } from '@prisma/client';

@Injectable()
export class UsersService {
  private readonly logger = new Logger(UsersService.name);

  constructor(private prisma: PrismaService) {}

  async findAll() {
    return this.prisma.user.findMany({
      where: { deletedAt: null },
      include: { driver: true },
      orderBy: { createdAt: 'desc' },
    });
  }

  async findOne(id: string) {
    const user = await this.prisma.user.findFirst({
      where: { id, deletedAt: null },
      include: { driver: true },
    });

    if (!user) {
      throw new NotFoundException(`User with ID ${id} not found`);
    }

    return user;
  }

  async update(id: string, updateUserDto: UpdateUserDto) {
    const user = await this.findOne(id);

    this.logger.log(`Updating user ${id}: ${JSON.stringify(updateUserDto)}`);

    // Handle role change and Driver record synchronization
    if (updateUserDto.role && updateUserDto.role !== user.role) {
      // If changing TO DRIVER role, create a Driver record if one doesn't exist
      if (updateUserDto.role === Role.DRIVER && !user.driver) {
        this.logger.log(
          `Creating Driver record for user ${user.email} (role change to DRIVER)`,
        );
        await this.prisma.driver.create({
          data: {
            name: user.name || user.email,
            phone: user.email, // Use email as placeholder for phone
            userId: user.id,
          },
        });
      }

      // If changing FROM DRIVER role to something else, remove the Driver record
      if (user.role === Role.DRIVER && updateUserDto.role !== Role.DRIVER && user.driver) {
        this.logger.log(
          `Removing Driver record for user ${user.email} (role change from DRIVER to ${updateUserDto.role})`,
        );
        await this.prisma.driver.delete({
          where: { id: user.driver.id },
        });
      }
    }

    return this.prisma.user.update({
      where: { id: user.id },
      data: updateUserDto,
      include: { driver: true },
    });
  }

  async approve(id: string, approveUserDto: ApproveUserDto) {
    const user = await this.findOne(id);

    this.logger.log(
      `${approveUserDto.isApproved ? 'Approving' : 'Denying'} user: ${user.email}`,
    );

    return this.prisma.user.update({
      where: { id: user.id },
      data: { isApproved: approveUserDto.isApproved },
      include: { driver: true },
    });
  }

  async remove(id: string) {
    const user = await this.findOne(id);

    this.logger.log(`Soft deleting user: ${user.email}`);

    return this.prisma.user.update({
      where: { id: user.id },
      data: { deletedAt: new Date() },
    });
  }

  async getPendingUsers() {
    return this.prisma.user.findMany({
      where: {
        deletedAt: null,
        isApproved: false,
      },
      orderBy: { createdAt: 'asc' },
    });
  }
}
