import {
	boolean,
	integer,
	jsonb,
	pgTable,
	serial,
	text,
	timestamp,
} from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import type { z } from "zod";

export const prodAuditLog = pgTable("prod_audit_log", {
	id: serial("id").primaryKey(),
	auditId: integer("audit_id").notNull().unique(),
	actorName: text("actor_name").notNull(),
	auditCreatedDate: timestamp("audit_created_date", {
		withTimezone: true,
	}).notNull(),
	message: text("message").notNull(), // mirrors how prod sends it over basically this is where the domain its coming from is. well split by "." and then pass it to what it needs to go to later.
	content: jsonb("content").notNull(),

	status: text("status").notNull().default("pending"), // pending | processing | success | error | dead
	processed: boolean("processed").default(false),

	retryCount: integer("retry_count").notNull().default(0),
	nextRetryAt: timestamp("next_retry_at", { withTimezone: true }),

	errorMessage: text("error_message"),
	errorStack: text("error_stack"),

	processedAt: timestamp("processed_at", { withTimezone: true }),

	createdAt: timestamp("created_at", { withTimezone: true }).defaultNow(),
	updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
});

export const prodAuditLogSchema = createSelectSchema(prodAuditLog);
export const newProdAuditLogSchema = createInsertSchema(prodAuditLog);

export type ProdAuditLog = z.infer<typeof prodAuditLogSchema>;
export type NewProdAuditLog = z.infer<typeof newProdAuditLogSchema>;

/*
if the system fails do the process we do 
and increase the retry to x max of 5 tries
const nextRetryAt = new Date(Date.now() + Math.min(30 * retryCount, 600) * 1000);

Cron every 30s
  ↓
Pull ERP AuditLog by Id > lastAuditId
  ↓
Insert into prod_audit_log
  ↓
Postgres NOTIFY wakes worker
  ↓
Worker processes pending rows
  ↓
Success = success
Failure = error + retryCount + nextRetryAt
20 failures = dead + email


for the check we want to do 

status IN ('pending', 'error')
AND retry_count < 20
AND (next_retry_at IS NULL OR next_retry_at <= NOW())

*/
