import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { ConfigService } from '@nestjs/config';
import { Request } from 'express';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from '../../entities/user.entity';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(
    config: ConfigService,
    @InjectRepository(User) private readonly userRepo: Repository<User>,
  ) {
    super({
      jwtFromRequest: ExtractJwt.fromExtractors([
        // 1. Standard Bearer header (existing behavior)
        ExtractJwt.fromAuthHeaderAsBearerToken(),
        // 2. SSE fallback: query string ?token=
        (req: Request) => {
          const token = req?.query?.token;
          if (typeof token === 'string' && token.length > 0) {
            return token;
          }
          return null;
        },
      ]),
      ignoreExpiration: false,
      secretOrKey: config.get('JWT_SECRET', 'dorm-billing-jwt-secret-key-2024'),
    });
  }

  async validate(payload: { sub?: number; username?: string }) {
    if (!payload.sub) throw new UnauthorizedException('登录状态无效');
    const user = await this.userRepo.findOne({
      where: { id: payload.sub },
      relations: ['roles', 'roles.permissions'],
    });
    if (!user || !user.isActive || user.isArchived) {
      throw new UnauthorizedException('账号已失效，请重新登录');
    }

    const permissions = new Set<string>();
    const roles: string[] = [];
    let isSuperAdmin = false;
    for (const role of user.roles ?? []) {
      if (role.status !== 1) continue;
      roles.push(role.name);
      if (role.name === '超管' || role.name === 'super_admin' || role.code === 'super_admin') {
        isSuperAdmin = true;
      }
      for (const permission of role.permissions ?? []) permissions.add(permission.code);
    }

    return {
      id: user.id,
      username: user.username,
      permissions: [...permissions],
      isSuperAdmin,
      roles,
    };
  }
}
