import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../infrastructure/database/prisma.service';

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

  // ═══ Notifications ═══

  async findAll(userId: string, pagination?: { page?: number; limit?: number }) {
    const page = pagination?.page ?? 1;
    const limit = pagination?.limit ?? 20;
    return this.prisma.notification.findMany({
      where: { userId },
      orderBy: { createdAt: 'desc' },
      skip: (page - 1) * limit,
      take: limit,
    });
  }

  async create(data: { userId: string; type: string; title: string; body: string }) {
    return this.prisma.notification.create({
      data: {
        userId: data.userId,
        type: data.type,
        title: data.title,
        content: data.body,
      },
    });
  }

  async findById(id: string) {
    return this.prisma.notification.findUnique({ where: { id } });
  }

  async markRead(id: string) {
    return this.prisma.notification.update({
      where: { id },
      data: { readAt: new Date() },
    });
  }

  async markAllRead(userId: string) {
    await this.prisma.notification.updateMany({
      where: { userId, readAt: null },
      data: { readAt: new Date() },
    });
  }

  async countUnread(userId: string) {
    return this.prisma.notification.count({
      where: { userId, readAt: null },
    });
  }

  // ═══ Preferences ═══

  async getPreference(userId: string) {
    let pref = await this.prisma.notificationPreference.findUnique({ where: { userId } });
    if (!pref) {
      pref = await this.prisma.notificationPreference.create({ data: { userId } });
    }
    return pref;
  }

  async updatePreference(userId: string, data: Record<string, any>) {
    await this.getPreference(userId); // ensure exists
    return this.prisma.notificationPreference.update({ where: { userId }, data });
  }

  // ═══ Push Tokens ═══

  async registerPushToken(userId: string, token: string, platform: string, deviceId?: string) {
    return this.prisma.pushToken.upsert({
      where: { userId_token: { userId, token } },
      update: { platform, deviceId, updatedAt: new Date() },
      create: { userId, token, platform, deviceId },
    });
  }

  async findPushTokens(userId: string) {
    return this.prisma.pushToken.findMany({ where: { userId } });
  }

  async removePushToken(userId: string, token: string) {
    return this.prisma.pushToken.deleteMany({ where: { userId, token } });
  }

  // ═══ Templates (Admin) ═══

  async findTemplates() {
    return this.prisma.notificationTemplate.findMany();
  }

  async findTemplateById(id: string) {
    return this.prisma.notificationTemplate.findUnique({ where: { id } });
  }

  async createTemplate(data: { name: string; type: string; title: string; content: string; channel?: string; createdBy?: string }) {
    return this.prisma.notificationTemplate.create({ data });
  }

  async updateTemplate(id: string, data: Record<string, any>) {
    return this.prisma.notificationTemplate.update({ where: { id }, data });
  }

  async deleteTemplate(id: string) {
    return this.prisma.notificationTemplate.delete({ where: { id } });
  }

  // ═══ Bulk send log (Admin) ═══

  async findRecentSent(limit = 100) {
    return this.prisma.notification.findMany({
      orderBy: { createdAt: 'desc' },
      take: limit,
    });
  }
}
