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

const jobSchema = new mongoose.Schema(
  {
    _reference: { type: String, default: () => generateId()() },
    state: {
      type: { required: true, type: String },
      progress: { type: Number, required: false },
    },
    printers: [{ type: Schema.Types.ObjectId, ref: 'printer', required: false }],
    createdAt: { required: true, type: Date },
    updatedAt: { required: true, type: Date },
    startedAt: { required: false, type: Date, default: null },
    finishedAt: { required: false, type: Date, default: null },
    gcodeFile: {
      type: Schema.Types.ObjectId,
      ref: 'gcodeFile',
      required: false,
    },
    quantity: {
      type: Number,
      required: true,
      default: 1,
      min: 1,
    },
    subJobs: [{ type: Schema.Types.ObjectId, ref: 'subJob', required: false }],
    notes: [{ type: Schema.Types.ObjectId, ref: 'note', required: false }],
  },
  { timestamps: true }
);

const rollupConfigs = [
  {
    name: 'queued',
    filter: { 'state.type': 'queued' },
    rollups: [{ name: 'queued', property: 'state.type', operation: 'count' }],
  },
  {
    name: 'printing',
    filter: { 'state.type': 'printing' },
    rollups: [{ name: 'printing', property: 'state.type', operation: 'count' }],
  },
  {
    name: 'draft',
    filter: { 'state.type': 'draft' },
    rollups: [{ name: 'draft', property: 'state.type', operation: 'count' }],
  },
  {
    name: 'complete',
    filter: { 'state.type': 'complete' },
    rollups: [{ name: 'complete', property: 'state.type', operation: 'count' }],
  },
  {
    name: 'failed',
    filter: { 'state.type': 'failed' },
    rollups: [{ name: 'failed', property: 'state.type', operation: 'count' }],
  },
];

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

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

jobSchema.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;
};

jobSchema.virtual('id').get(function () {
  return this._id;
});

jobSchema.set('toJSON', { virtuals: true });

export const jobModel = mongoose.model('job', jobSchema);
