import { Injectable, NestInterceptor, ExecutionContext, CallHandler, UnauthorizedException } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { PrismaService } from '../prisma.service';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class SessionActivityInterceptor implements NestInterceptor {
  private readonly inactivityMinutes: number;

  constructor(
    private readonly prisma: PrismaService,
    private readonly config: ConfigService,
  ) {
    this.inactivityMinutes = parseInt(this.config.get<string>('SESSION_INACTIVITY_MINUTES') || '30', 10);
  }

  async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {
    const request = context.switchToHttp().getRequest();
    const response = context.switchToHttp().getResponse();
    const user = request.user;

    if (user?.userId) {
      const session = await this.prisma.session.findFirst({
        where: { userId: user.userId },
        orderBy: { lastActivityAt: 'desc' },
      });

      if (session) {
        const inactiveMinutes = (Date.now() - session.lastActivityAt.getTime()) / 60000;
        
        if (inactiveMinutes > this.inactivityMinutes) {
          await this.prisma.session.delete({ where: { id: session.id } });
          throw new UnauthorizedException('Session expired due to inactivity');
        }

        const expiryWarningMinutes = Math.max(0, this.inactivityMinutes - inactiveMinutes);
        response.setHeader('X-Session-Expiry-Warning', Math.floor(expiryWarningMinutes).toString());

        await this.prisma.session.update({
          where: { id: session.id },
          data: { lastActivityAt: new Date() },
        });
      }
    }

    return next.handle().pipe(tap(() => {}));
  }
}
