import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Request } from 'express';
import { map, Observable } from 'rxjs';

export interface ResponsePayload<T> {
  message?: string;
  data?: T;
}

type PublicApiRequest = Request & { publicApiEncrypted?: boolean };

@Injectable()
export class ResponseInterceptor<T> implements NestInterceptor<T, unknown> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
    const request = context.switchToHttp().getRequest<PublicApiRequest>();
    if (request.path.startsWith('/internal/crypto') || request.publicApiEncrypted) {
      return next.handle();
    }

    return next.handle().pipe(
      map((value: ResponsePayload<T> | T) => {
        if (value && typeof value === 'object' && 'success' in value) return value;
        const payload = value as ResponsePayload<T>;
        if (payload && typeof payload === 'object' && ('message' in payload || 'data' in payload)) {
          return { success: true, message: payload.message ?? 'Request successful', data: payload.data ?? null };
        }
        return { success: true, message: 'Request successful', data: value ?? null };
      }),
    );
  }
}
