import mongoose from 'mongoose';
import { ProductCategory, ServingUnit, ProductSource } from '@meshitrack/shared';

const nutritionInfoSchema = new mongoose.Schema(
  {
    calories: { type: Number, required: true, min: 0 },
    protein: { type: Number, required: true, min: 0 },
    carbs: { type: Number, required: true, min: 0 },
    fat: { type: Number, required: true, min: 0 },
    fiber: { type: Number, min: 0 },
    sugar: { type: Number, min: 0 },
    sodium: { type: Number, min: 0 },
    saturatedFat: { type: Number, min: 0 },
    cholesterol: { type: Number, min: 0 },
  },
  { _id: false },
);

const productSchema = new mongoose.Schema(
  {
    householdId: { type: String, required: true },
    name: { type: String, required: true },
    brand: { type: String },
    barcode: { type: String },
    category: { type: String, enum: Object.values(ProductCategory), required: true },
    servingSize: { type: Number, required: true, min: 0 },
    servingUnit: { type: String, enum: Object.values(ServingUnit), required: true },
    densityGPerMl: { type: Number, min: 0 },
    nutrition: { type: nutritionInfoSchema, required: true },
    tags: { type: [String], default: [] },
    imageUrl: { type: String },
    source: {
      type: String,
      enum: Object.values(ProductSource),
      required: true,
      default: ProductSource.MANUAL,
    },
    createdBy: { type: String, required: true },
    deletedAt: { type: Date },
  },
  {
    timestamps: true,
    toJSON: { virtuals: true },
    toObject: { virtuals: true },
  },
);

productSchema.index(
  { householdId: 1, name: 'text', brand: 'text', tags: 'text' },
  { name: 'product_text_search' },
);
productSchema.index({ householdId: 1, deletedAt: 1, category: 1 });
productSchema.index(
  { householdId: 1, barcode: 1 },
  {
    name: 'product_barcode_unique',
    unique: true,
    partialFilterExpression: { barcode: { $exists: true }, deletedAt: { $exists: false } },
  },
);
productSchema.index({ householdId: 1, name: 1, brand: 1 }, { name: 'product_dedup' });

export const ProductModel = mongoose.model('Product', productSchema);
export type ProductDocument = mongoose.InferSchemaType<typeof productSchema> & {
  _id: mongoose.Types.ObjectId;
};
