import { Injectable } from "@nestjs/common";
import {
  EmailNotificationServicio,
  EmailNotificationStatus,
  EmailNotificationType,
} from "@jorgecuadros/database";
import { PrismaService } from "../prisma/prisma.service";
import { AttemptStatus } from "./notification.types";

/**
 * The single writer for `email_notification_log`.
 *
 * Extracted out of `NotificationsService` so the renewal sweep can write the
 * same rows as the four bulk jobs without pulling that service (and its four
 * job pipelines) into `RenewalsModule`. Every outbound email the platform
 * sends goes through here, which is what makes /notificaciones' "Registro de
 * envíos" complete rather than per-feature.
 */
export interface NotificationLogEntry {
  notificationType: EmailNotificationType;
  servicio: EmailNotificationServicio;
  /** Defaults to now(). Pass it when the row must line up exactly with
   *  another record of the same send (the renewal sweep pins it to
   *  `RenewalNotice.sentAt`). */
  sendDate?: Date;
  /** Type-dependent discriminator — see the `level` doc on the Prisma model.
   *  0/1 for ACCOUNT_STATUS, the generation for RENEWAL_NOTICE. */
  level?: number | null;
  customerId: string | null;
  customerName: string;
  customerEmail: string;
  subject: string;
  bodySnapshot: string;
  bodyRequestUrl?: string;
  status: AttemptStatus;
  debug: boolean;
  providerMessageId?: string;
  providerResponse?: string;
  error?: string;
}

/** `providerResponse` is a VARCHAR(191); anything longer is a provider dump
 *  we only need the head of. Errors go to the TEXT `error` column and get
 *  the 4k cap the schema documents. */
const PROVIDER_RESPONSE_MAX = 180;
const ERROR_MAX = 4096;

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

  async record(entry: NotificationLogEntry): Promise<void> {
    await this.prisma.emailNotificationLog.create({
      data: {
        notificationType: entry.notificationType,
        servicio: entry.servicio,
        ...(entry.sendDate && { sendDate: entry.sendDate }),
        level: entry.level ?? null,
        customerId: entry.customerId,
        customerName: entry.customerName,
        customerEmail: entry.customerEmail,
        subject: entry.subject,
        bodySnapshot: entry.bodySnapshot,
        bodyRequestUrl: entry.bodyRequestUrl ?? null,
        debug: entry.debug,
        providerMessageId: entry.providerMessageId ?? null,
        providerResponse:
          entry.providerResponse?.slice(0, PROVIDER_RESPONSE_MAX) ?? null,
        status: entry.status as EmailNotificationStatus,
        error: entry.error?.slice(0, ERROR_MAX) ?? null,
      },
    });
  }
}
