import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import * as webpush from 'web-push';
import { PushSubscription } from './entities/push-subscription.entity';

@Injectable()
export class PushService {
  private readonly logger = new Logger(PushService.name);

  constructor(
    @InjectRepository(PushSubscription, 'scheme_dbs')
    private readonly subRepo: Repository<PushSubscription>,
  ) {
    // ✅ MOVED HERE — runs after ConfigModule has loaded .env
    webpush.setVapidDetails(
      process.env.VAPID_SUBJECT!,
      process.env.VAPID_PUBLIC_KEY!,
      process.env.VAPID_PRIVATE_KEY!,
    );
  }

  async subscribe(userId: number, subscription: any): Promise<void> {
    // ✅ REPLACE upsert with manual find + save
    const existing = await this.subRepo.findOne({
      where: { endpoint: subscription.endpoint },
    });

    if (existing) {
      // Update existing subscription
      existing.user_id = userId;
      // 🔧 CHANGED: split "keys" JSON → 2 columns p256dh + auth (matches DB)
      existing.p256dh = subscription.keys.p256dh;
      existing.auth = subscription.keys.auth;
      await this.subRepo.save(existing);
    } else {
      // Insert new subscription
      const newSub = this.subRepo.create({
        user_id: userId,
        endpoint: subscription.endpoint,
        // 🔧 CHANGED: split "keys" JSON → 2 columns p256dh + auth (matches DB)
        p256dh: subscription.keys.p256dh,
        auth: subscription.keys.auth,
      });
      await this.subRepo.save(newSub);
    }
  }

  async sendToUsers(userIds: number[], payload: object): Promise<void> {
    if (!userIds.length) return;
    const subs = await this.subRepo
      .createQueryBuilder('s')
      .where('s.user_id IN (:...userIds)', { userIds })
      .getMany();

    const json = JSON.stringify(payload);
    for (const sub of subs) {
      try {
        await webpush.sendNotification(
          // 🔧 CHANGED: build keys object from 2 columns (matches DB)
          {
            endpoint: sub.endpoint,
            keys: { p256dh: sub.p256dh, auth: sub.auth },
          },
          json,
        );
      } catch (err: any) {
        if (err.statusCode === 410) {
          await this.subRepo.delete(sub.id);
        } else {
          this.logger.warn(
            `Push failed for user ${sub.user_id}: ${err.message}`,
          );
        }
      }
    }
  }
}