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

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

  constructor(private prisma: PrismaService) {}

  /**
   * Validate and get/create user from Auth0 token payload
   */
  async validateUser(payload: any) {
    const namespace = 'https://vip-coordinator-api';
    const auth0Id = payload.sub;
    const email = payload[`${namespace}/email`] || payload.email || `${auth0Id}@auth0.local`;
    const name = payload[`${namespace}/name`] || payload.name || 'Unknown User';
    const picture = payload[`${namespace}/picture`] || payload.picture;

    // Check if user exists (exclude soft-deleted users)
    let user = await this.prisma.user.findFirst({
      where: { auth0Id, deletedAt: null },
      include: { driver: true },
    });

    if (!user) {
      // Use serializable transaction to prevent race condition
      // where two simultaneous registrations both become admin
      user = await this.prisma.$transaction(async (tx) => {
        const approvedUserCount = await tx.user.count({
          where: { isApproved: true, deletedAt: null },
        });
        const isFirstUser = approvedUserCount === 0;

        this.logger.log(
          `Creating new user: ${email} (approvedUserCount: ${approvedUserCount}, isFirstUser: ${isFirstUser})`,
        );

        // First user is auto-approved as ADMINISTRATOR
        // Subsequent users default to DRIVER and require approval
        const newUser = await tx.user.create({
          data: {
            auth0Id,
            email,
            name,
            picture,
            role: isFirstUser ? Role.ADMINISTRATOR : Role.DRIVER,
            isApproved: isFirstUser,
          },
          include: { driver: true },
        });

        this.logger.log(
          `User created: ${newUser.email} with role ${newUser.role} (approved: ${newUser.isApproved})`,
        );

        return newUser;
      }, { isolationLevel: 'Serializable' });
    }

    return user;
  }

  /**
   * Get current user profile (excludes soft-deleted users)
   */
  async getCurrentUser(auth0Id: string) {
    return this.prisma.user.findFirst({
      where: { auth0Id, deletedAt: null },
      include: { driver: true },
    });
  }
}
