import {
  EmailNotificationServicio,
  EmailNotificationType,
} from "@jorgecuadros/database";
import { IsBoolean, IsEnum, IsOptional } from "class-validator";

/**
 * Where `debug` sends everything. The PHP used `rmancinas@freakma.net`;
 * same here. Exported because the flag is platform-wide — the renewal
 * notices honour it too, and two copies of this address would eventually
 * disagree.
 */
export const DEBUG_RECIPIENT = "rmancinas@freakma.net";

/**
 * Shared flags for every notification send — the four servicios jobs and
 * the pólizas renewal notices alike. Every endpoint takes the same shape
 * so the UI can offer one set of switches for the whole screen; each flag
 * is documented inline so the per-job semantics are obvious in one place.
 *
 * `debug`            — replace every recipient with `DEBUG_RECIPIENT` so a
 *                      real customer never receives mail during a test run.
 *                      Logged on every row. On the renewal side a debug send
 *                      also does NOT write the `RenewalNotice` row, so a test
 *                      can't gate the letter the customer is still owed.
 * `ignoreDayRestriction` — Job 3 only: bypass the Mon/Wed/Fri (red) and
 *                      Wed-only (yellow) day gates. Off by default so
 *                      the on-demand sweep behaves like the legacy
 *                      script.
 * `useEmailLimit`    — Job 3 only: pause the sweep 1 hour after 100
 *                      sends (a vestigial SMTP-era throttling limit).
 *                      Off by default; SES does not need it.
 */
export class NotificationFlagsDto {
  @IsOptional()
  @IsBoolean()
  debug?: boolean;

  @IsOptional()
  @IsBoolean()
  ignoreDayRestriction?: boolean;

  @IsOptional()
  @IsBoolean()
  useEmailLimit?: boolean;
}

/**
 * What we know at job-end and put on the wire. Field names match the
 * legacy PHP scripts' `echo json_encode(...)` so a downstream log scraper
 * that already parses `notificationType: "sendPaymentConfirmation"`
 * keeps working — see `~/Documents/Claude-Memory/email-notifications-spec.md`
 * for the verbatim PHP shapes. Specifically: Job 1 reports
 * `notificationType: "sendPaymentConfirmation"` (the legacy literal), and
 * uses field `result` instead of `request`; the other three use
 * `notificationType` matching the script's purpose.
 *
 * Every variant carries `sent/skipped/failed/debug` for the audit log;
 * the legacy fields stay where they were so the response shape is
 * exactly backward-compatible.
 */
export type NotificationJobResponse =
  | {
      // Job 1
      result: "success";
      notificationType: "sendPaymentConfirmation";
      reason: string;
      statusCode: 200;
      sent: number;
      skipped: number;
      failed: number;
      debug: boolean;
      type: "OUTSTANDING_PAYMENT";
    }
  | {
      // Job 2
      request: "success";
      notificationType: "sendPaymentConfirmation";
      confirmationSent: string;
      statusCode: 200;
      sent: number;
      skipped: number;
      failed: number;
      debug: boolean;
      type: "PAYMENT_CONFIRMATION";
    }
  | {
      // Job 3 — sent/skipped/failed included so the audit log can record
      // totals without depending on (red+yellow) alone.
      request: "success";
      notificationType: "sendAccountStatus";
      statusSent: string;
      statusReport: string;
      statusCode: 200;
      red: number;
      yellow: number;
      total: number;
      sent: number;
      skipped: number;
      failed: number;
      debug: boolean;
      type: "ACCOUNT_STATUS";
    }
  | {
      // Job 4
      request: "success";
      notificationType: "sendTrustPaymentConfirmation";
      confirmationSent: string;
      statusCode: 200;
      sent: number;
      skipped: number;
      failed: number;
      debug: boolean;
      type: "TRUST_PAYMENT_CONFIRMATION";
    };

/** The four jobs, in the order the "ejecutar todos" sweep runs them. */
export type NotificationJobKind =
  | "outstanding"
  | "payment"
  | "account"
  | "trust";

/**
 * One entry of the run-all sweep. A job that throws does NOT abort the
 * sweep — it is recorded with `ok: false` and the next job still runs, so a
 * single bad query can't silently block the other three envíos.
 */
export interface NotificationRunAllJobResult {
  kind: NotificationJobKind;
  ok: boolean;
  result?: NotificationJobResponse;
  error?: string;
}

/**
 * Aggregate response for `POST /notifications/run-all`. `sent/skipped/failed`
 * are the sums across every job that completed; `jobs` keeps each job's own
 * verbatim legacy response so the UI can still show per-job detail.
 */
export interface NotificationRunAllResponse {
  request: "success";
  notificationType: "runAllNotifications";
  statusCode: 200;
  debug: boolean;
  sent: number;
  skipped: number;
  failed: number;
  /** Jobs that threw — sweep continued past them. */
  errors: number;
  jobs: NotificationRunAllJobResult[];
  type: "RUN_ALL";
}

/** Normalized record for a single send attempt, fed by all four jobs. */
export interface SendAttempt {
  notificationType: EmailNotificationType;
  servicio: EmailNotificationServicio;
  customerId: string | null;
  customerName: string;
  customerEmail: string;
  subject: string;
  bodySnapshot: string;
  bodyRequestUrl?: string;
  /** Account-status-only — 0 yellow / 1 red. Null on the other three jobs. */
  level?: 0 | 1;
  /** Account-status-only — DEBAJO DEL TIPO / EN ROJO. */
  historyTipo?: string;
  historyBalance?: string;
  historyTCambio?: string;
  historySolicitado?: string;
}

/** Status enum values, mirrored from `EmailNotificationStatus`. */
export type AttemptStatus = "SENT" | "FAILED" | "SKIPPED_NO_EMAIL" | "SKIPPED_GATE";
