import {
  Injectable,
  UnauthorizedException,
  BadRequestException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UsersService } from '../users/users.service';
import { PrismaService } from '../prisma/prisma.service';
import * as bcrypt from 'bcrypt';

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

  async validateUser(
    username: string,
    password: string,
    tenantId?: number,
  ): Promise<any> {
    const user = await this.usersService.findByUsername(username, tenantId);
    if (user && (await bcrypt.compare(password, user.password))) {
      // 验证租户是否匹配
      if (tenantId && user.tenantId !== tenantId) {
        throw new UnauthorizedException('用户不属于该租户');
      }
      const { password, ...result } = user;
      password;
      return result;
    }
    return null;
  }

  async login(user: any, tenantId?: number) {
    // 确保租户ID存在
    const finalTenantId = tenantId || user.tenantId;
    if (!finalTenantId) {
      throw new BadRequestException('无法确定租户信息');
    }

    // 验证租户是否有效
    const tenant = await this.prisma.tenant.findUnique({
      where: { id: finalTenantId },
    });

    if (!tenant) {
      throw new BadRequestException('租户不存在');
    }

    if (tenant.validState !== 1) {
      throw new BadRequestException('租户已失效');
    }

    // 验证用户是否属于该租户
    if (user.tenantId !== finalTenantId) {
      throw new UnauthorizedException('用户不属于该租户');
    }

    const payload = {
      username: user.username,
      sub: user.id,
      tenantId: finalTenantId,
    };

    return {
      token: this.jwtService.sign(payload),
      user: {
        id: user.id,
        username: user.username,
        nickname: user.nickname,
        email: user.email,
        avatar: user.avatar,
        tenantId: finalTenantId,
        tenantCode: tenant.code,
        roles: user.roles?.map((ur: any) => ur.role.code) || [],
        permissions: await this.getUserPermissions(user.id),
      },
    };
  }

  async getUserInfo(userId: number) {
    const user = await this.usersService.findOne(userId);
    if (!user) {
      throw new UnauthorizedException('用户不存在');
    }

    const tenant = await this.prisma.tenant.findUnique({
      where: { id: user.tenantId },
    });

    return {
      id: user.id,
      username: user.username,
      nickname: user.nickname,
      email: user.email,
      avatar: user.avatar,
      tenantId: user.tenantId,
      tenantCode: tenant?.code,
      roles: user.roles?.map((ur: any) => ur.role.code) || [],
      permissions: await this.getUserPermissions(userId),
    };
  }

  async getUserPermissions(userId: number): Promise<string[]> {
    const user = await this.usersService.findOne(userId);
    if (!user) return [];

    const permissions = new Set<string>();
    user.roles?.forEach((ur: any) => {
      ur.role.permissions?.forEach((rp: any) => {
        permissions.add(rp.permission.code);
      });
    });

    return Array.from(permissions);
  }

  async getUserRoles(userId: number): Promise<string[]> {
    const user = await this.usersService.findOne(userId);
    if (!user) return [];

    return user.roles?.map((ur: any) => ur.role.code) || [];
  }
}
