import {
  Controller,
  Post,
  Get,
  Delete,
  Body,
  Req,
  UseGuards,
  HttpCode,
  HttpStatus,
  Query,
  BadRequestException,
} from '@nestjs/common';
import { PushService, PushSubscriptionData } from './push.service';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { Public } from '../auth/decorators/public.decorator';

@Controller('api/v1/push')
export class PushController {
  constructor(private readonly pushService: PushService) {}

  /**
   * Get the public VAPID key for frontend subscription
   * This endpoint is public since it's needed for subscription setup
   */
  @Public()
  @Get('vapid-public-key')
  @HttpCode(HttpStatus.OK)
  getPublicKey(): { publicKey: string } {
    return {
      publicKey: this.pushService.getPublicVapidKey(),
    };
  }

  /**
   * Subscribe to push notifications
   */
  @Post('subscriptions')
  @UseGuards(JwtAuthGuard)
  @HttpCode(HttpStatus.CREATED)
  async subscribe(
    @Req() req: any,
    @Body() subscriptionData: PushSubscriptionData,
  ) {
    const userId = req.user?.userId;

    if (!subscriptionData?.endpoint || !subscriptionData?.keys) {
      throw new BadRequestException(
        'Invalid subscription data. Must include endpoint and keys (p256dh, auth)',
      );
    }

    if (!subscriptionData.keys.p256dh || !subscriptionData.keys.auth) {
      throw new BadRequestException(
        'Invalid subscription keys. Must include p256dh and auth',
      );
    }

    const userAgent = req.headers['user-agent'];

    const subscription = await this.pushService.subscribe(
      userId,
      subscriptionData,
      userAgent,
    );

    return {
      id: subscription.id,
      endpoint: subscription.endpoint,
      createdAt: subscription.createdAt,
      deviceType: subscription.deviceType,
      browser: subscription.browser,
    };
  }

  /**
   * Get user's push subscriptions
   */
  @Get('subscriptions')
  @UseGuards(JwtAuthGuard)
  @HttpCode(HttpStatus.OK)
  async getSubscriptions(@Req() req: any) {
    const userId = req.user?.userId;
    const subscriptions = await this.pushService.getUserSubscriptions(userId);

    return {
      subscriptions: subscriptions.map((sub) => ({
        id: sub.id,
        endpoint: sub.endpoint.substring(0, 50) + '...', // Truncate for security
        deviceType: sub.deviceType,
        browser: sub.browser,
        isActive: sub.isActive,
        createdAt: sub.createdAt,
        lastSuccessAt: sub.lastSuccessAt,
      })),
      total: subscriptions.length,
    };
  }

  /**
   * Unsubscribe from push notifications
   */
  @Delete('subscriptions')
  @UseGuards(JwtAuthGuard)
  @HttpCode(HttpStatus.NO_CONTENT)
  async unsubscribe(@Req() req: any, @Query('endpoint') endpoint: string) {
    const userId = req.user?.userId;

    if (!endpoint) {
      throw new BadRequestException('Endpoint query parameter is required');
    }

    await this.pushService.unsubscribe(userId, endpoint);
  }

  /**
   * Send a test push notification
   */
  @Post('test')
  @UseGuards(JwtAuthGuard)
  @HttpCode(HttpStatus.OK)
  async sendTest(@Req() req: any) {
    const userId = req.user?.userId;
    await this.pushService.sendTestNotification(userId);

    return {
      message: 'Test notification sent',
    };
  }

  /**
   * Get push notification statistics (admin or self)
   */
  @Get('statistics')
  @UseGuards(JwtAuthGuard)
  @HttpCode(HttpStatus.OK)
  async getStatistics(@Req() req: any) {
    const userId = req.user?.userId;
    const stats = await this.pushService.getStatistics(userId);

    return stats;
  }
}
