import mongoose, { Schema, models, model } from "mongoose";

export const SYSTEM_LOG_LEVELS = ["error", "warn", "info"] as const;
export type SystemLogLevel = (typeof SYSTEM_LOG_LEVELS)[number];

// Grobe technische Herkunft des Eintrags — nicht die fachliche Kategorie der
// Logs-Ansicht (die führt SystemLog mit mehreren Aktivitäts-Quellen zusammen).
export const SYSTEM_LOG_SOURCES = ["render", "route", "action", "client", "cron", "system"] as const;
export type SystemLogSource = (typeof SYSTEM_LOG_SOURCES)[number];

export interface SystemLogDoc {
  _id: string;
  level: SystemLogLevel;
  source: SystemLogSource;
  message: string;
  stack: string;
  digest: string;
  route: string;
  method: string;
  statusCode: number | null;
  actorId: mongoose.Types.ObjectId | null;
  // sha1(message + oberster Stack-Frame), gekürzt — gruppiert wiederkehrende
  // identische Fehler in der Ansicht ("× 3"), ohne Zähler mutieren zu müssen.
  fingerprint: string;
  context: Record<string, unknown>;
  createdAt: Date;
}

const systemLogSchema = new Schema<SystemLogDoc>(
  {
    level: { type: String, enum: SYSTEM_LOG_LEVELS, default: "error", index: true },
    source: { type: String, enum: SYSTEM_LOG_SOURCES, default: "render", index: true },
    message: { type: String, required: true, trim: true, maxlength: 2000 },
    stack: { type: String, default: "", maxlength: 12000 },
    digest: { type: String, default: "", trim: true, maxlength: 120 },
    route: { type: String, default: "", trim: true, maxlength: 400 },
    method: { type: String, default: "", trim: true, maxlength: 16 },
    statusCode: { type: Number, default: null },
    actorId: { type: Schema.Types.ObjectId, ref: "Client", default: null },
    fingerprint: { type: String, default: "", trim: true, maxlength: 80, index: true },
    context: { type: Schema.Types.Mixed, default: {} },
  },
  { timestamps: { createdAt: true, updatedAt: false } }
);

// Aufbewahrung 90 Tage — der MongoDB-TTL-Monitor räumt selbst auf, kein Cron.
systemLogSchema.index({ createdAt: 1 }, { expireAfterSeconds: 60 * 60 * 24 * 90 });
systemLogSchema.index({ level: 1, createdAt: -1 });

export const SystemLog =
  (models.SystemLog as mongoose.Model<SystemLogDoc>) || model<SystemLogDoc>("SystemLog", systemLogSchema);
