/**
 * Auth Service
 *
 * Replaces: PublicDataImpl Connect(), SetDatabaseName(), Disconnect()
 * Original COM methods for database connection and credentials.
 *
 * This service validates users against the Users table and issues JWT tokens.
 * Database selection is passed in login - Prisma uses DATABASE_URL;
 * for multi-database support, you'd use connection pooling per tenant.
 */
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { PrismaService } from '../prisma/prisma.service';
import * as bcrypt from 'bcrypt';
import { LoginDto } from './dto/login.dto';

export interface LoginResponse {
  accessToken: string;
  expiresIn: string;
  user: {
    id: number;
    name: string;
    type: number;
    privileges?: string;
  };
}

@Injectable()
export class AuthService {
  constructor(
    private prisma: PrismaService,
    private jwtService: JwtService,
  ) {}

  /**
   * Login - validates credentials and returns JWT
   * Maps to: Connect() in PublicDataImpl
   */
  async login(dto: LoginDto): Promise<LoginResponse> {
    // Find user by name (original server uses Users table)
    const user = await this.prisma.user.findFirst({
      where: { name: dto.userName },
    });

    if (!user || !user.pass) {
      throw new UnauthorizedException('Invalid username or password');
    }

    // Compare password (original may use plain text - adjust as needed)
    const isMatch =
      user.pass === dto.password ||
      (await bcrypt.compare(dto.password, user.pass));

    if (!isMatch) {
      throw new UnauthorizedException('Invalid username or password');
    }

    const payload = {
      sub: user.id,
      username: user.name,
      dbName: dto.dbName,
      dbType: dto.dbType ?? 2,
    };

    const accessToken = this.jwtService.sign(payload);

    return {
      accessToken,
      expiresIn: process.env.JWT_EXPIRES_IN || '1d',
      user: {
        id: user.id,
        name: user.name ?? '',
        type: user.type,
        privileges: user.privileges ?? '',
      },
    };
  }

  /**
   * Validate user by ID (used by JWT strategy)
   */
  async validateUser(userId: number) {
    return this.prisma.user.findUnique({
      where: { id: userId },
      select: { id: true, name: true, type: true, privileges: true },
    });
  }
}
