import mongoose from 'mongoose';
import { generateId } from '../../utils.js';
const { Schema } = mongoose;
import { aggregateRollups, aggregateRollupsHistory } from '../../database.js';

// Define the moonraker connection schema
const moonrakerSchema = new Schema(
  {
    host: { type: String, required: true },
    port: { type: Number, required: true },
    protocol: { type: String, required: true },
    apiKey: { type: String, default: null, required: false },
  },
  { _id: false }
);

const alertSchema = new Schema(
  {
    type: { type: String, required: true }, // error, info, message
    message: { type: String, required: false },
    actions: [{ type: String, required: false, default: [] }],
    _id: { type: String, required: true },
    canDismiss: { type: Boolean, required: true, default: true },
  },
  { timestamps: true, _id: false }
);

// Define the main printer schema
const printerSchema = new Schema(
  {
    _reference: { type: String, default: () => generateId()() },
    name: { type: String, required: true },
    online: { type: Boolean, required: true, default: false },
    active: { type: Boolean, required: true, default: true },
    state: {
      type: { type: String, required: true, default: 'offline' },
      message: { type: String, required: false },
      progress: { type: Number, required: false },
    },
    connectedAt: { type: Date, default: null },
    loadedFilament: {
      type: Schema.Types.ObjectId,
      ref: 'filament',
      default: null,
    },
    moonraker: { type: moonrakerSchema, required: true },
    tags: [{ type: String }],
    firmware: { type: String },
    currentJob: { type: Schema.Types.ObjectId, ref: 'job' },
    currentSubJob: { type: Schema.Types.ObjectId, ref: 'subJob' },
    currentFilamentStock: { type: Schema.Types.ObjectId, ref: 'filamentStock' },
    queue: [{ type: Schema.Types.ObjectId, ref: 'subJob' }],
    vendor: { type: Schema.Types.ObjectId, ref: 'vendor', default: null },
    host: { type: Schema.Types.ObjectId, ref: 'host', default: null },
    alerts: [alertSchema],
  },
  { timestamps: true }
);

const rollupConfigs = [
  {
    name: 'standby',
    filter: { 'state.type': 'standby' },
    rollups: [{ name: 'standby', property: 'state.type', operation: 'count' }],
  },
  {
    name: 'complete',
    filter: { 'state.type': 'complete' },
    rollups: [{ name: 'complete', property: 'state.type', operation: 'count' }],
  },
  {
    name: 'printing',
    filter: { 'state.type': 'printing' },
    rollups: [{ name: 'printing', property: 'state.type', operation: 'count' }],
  },
  {
    name: 'error',
    filter: { 'state.type': 'error' },
    rollups: [{ name: 'error', property: 'state.type', operation: 'count' }],
  },
  {
    name: 'offline',
    filter: { 'state.type': 'offline' },
    rollups: [{ name: 'offline', property: 'state.type', operation: 'count' }],
  },
];

printerSchema.statics.stats = async function () {
  const results = await aggregateRollups({
    model: this,
    baseFilter: { active: true },
    rollupConfigs: rollupConfigs,
  });

  console.log(results);

  // Transform the results to match the expected format
  return results;
};

printerSchema.statics.history = async function (from, to) {
  const results = await aggregateRollupsHistory({
    model: this,
    startDate: from,
    endDate: to,
    rollupConfigs: rollupConfigs,
  });

  // Return time-series data array
  return results;
};

// Add virtual id getter
printerSchema.virtual('id').get(function () {
  return this._id;
});

// Configure JSON serialization to include virtuals
printerSchema.set('toJSON', { virtuals: true });

// Create and export the model
export const printerModel = mongoose.model('printer', printerSchema);
