import { BadRequestException, Injectable, Logger } from '@nestjs/common';
import { PushPlatform } from '../generated/prisma/client';
import { PrismaService } from '../infra/prisma.service';

const VALID_PLATFORMS = new Set<string>(['WEB', 'ANDROID', 'IOS']);

@Injectable()
export class PushDeviceService {
  constructor(private readonly prisma: PrismaService) {}

  async register(userId: string, token: string, platform: string, deviceLabel?: string) {
    const normalizedToken = token?.trim();
    if (!normalizedToken) {
      throw new BadRequestException('Укажите FCM-токен устройства');
    }

    const normalizedPlatform = (platform?.trim().toUpperCase() || 'WEB') as PushPlatform;
    if (!VALID_PLATFORMS.has(normalizedPlatform)) {
      throw new BadRequestException('Недопустимая платформа push-уведомлений');
    }

    const existingOwner = await this.prisma.pushDeviceToken.findUnique({
      where: { token: normalizedToken }
    });

    if (existingOwner && existingOwner.userId !== userId) {
      await this.prisma.pushDeviceToken.delete({ where: { token: normalizedToken } });
    }

    await this.prisma.pushDeviceToken.upsert({
      where: { token: normalizedToken },
      create: {
        userId,
        token: normalizedToken,
        platform: normalizedPlatform,
        deviceLabel: deviceLabel?.trim() || null
      },
      update: {
        userId,
        platform: normalizedPlatform,
        deviceLabel: deviceLabel?.trim() || null
      }
    });

    return { count: 1 };
  }

  async unregister(userId: string, token: string) {
    const normalizedToken = token?.trim();
    if (!normalizedToken) {
      throw new BadRequestException('Укажите FCM-токен устройства');
    }

    const result = await this.prisma.pushDeviceToken.deleteMany({
      where: { userId, token: normalizedToken }
    });

    return { count: result.count };
  }

  async listTokensForUser(userId: string) {
    return this.prisma.pushDeviceToken.findMany({
      where: { userId },
      orderBy: { updatedAt: 'desc' }
    });
  }

  async removeTokens(tokens: string[]) {
    if (!tokens.length) return { count: 0 };
    const result = await this.prisma.pushDeviceToken.deleteMany({
      where: { token: { in: tokens } }
    });
    return { count: result.count };
  }
}
