import mongoose from 'mongoose';
import { getVariants, getVariantStatus, getTotalStock } from '../utils/variantUtils.js';

const sizeVariantSchema = new mongoose.Schema(
  {
    size: { type: String, required: true },
    stock: { type: Number, default: 0, min: [0, 'Stock cannot be negative'] },
    lowStockThreshold: { type: Number, default: 5, min: [0, 'Threshold cannot be negative'] },
  },
  { _id: false }
);

const variantSchema = new mongoose.Schema(
  {
    variantId: { type: String, required: true, trim: true },
    label: { type: String, required: true, trim: true },
    size: { type: String, default: null, trim: true },
    measurementValue: { type: Number, default: null },
    measurementUnit: { type: String, default: null, trim: true },
    sellingUnit: { type: String, default: 'pcs', trim: true },
    purchasePrice: { type: Number, default: 0, min: [0, 'Purchase price cannot be negative'] },
    sellingPrice: { type: Number, default: 0, min: [0, 'Selling price cannot be negative'] },
    currentStock: { type: Number, default: 0, min: [0, 'Stock cannot be negative'] },
    lowStockThreshold: { type: Number, default: 10, min: [0, 'Threshold cannot be negative'] },
    sku: { type: String, default: '', trim: true },
    barcode: { type: String, default: '', trim: true },
    status: { type: String, default: 'ACTIVE' },
  },
  { _id: false }
);

const productSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: [true, 'Product name is required'],
      trim: true,
      index: true,
    },
    category: {
      type: String,
      required: [true, 'Category is required'],
      trim: true,
      index: true,
    },
    image: {
      type: String,
      default: '',
    },
    trackingType: {
      type: String,
      enum: ['QUANTITY', 'WEIGHT', 'VOLUME', 'SIZE'],
      default: 'QUANTITY',
    },
    unit: {
      type: String,
      default: 'pcs',
      trim: true,
    },
    sizeSystem: {
      type: String,
      enum: ['CLOTHING', 'SHOES', ''],
      default: '',
    },
    sizeVariants: {
      type: [sizeVariantSchema],
      default: [],
    },
    variants: {
      type: [variantSchema],
      default: [],
    },
    purchasePrice: {
      type: Number,
      default: 0,
      min: [0, 'Purchase price cannot be negative'],
    },
    sellingPrice: {
      type: Number,
      default: 0,
      min: [0, 'Selling price cannot be negative'],
    },
    discountRules: {
      tier1: { min: { type: Number, default: 1 }, max: { type: Number, default: 4 }, discount: { type: Number, default: 0 } },
      tier2: { min: { type: Number, default: 5 }, max: { type: Number, default: 9 }, discount: { type: Number, default: 5 } },
      tier3: { min: { type: Number, default: 10 }, max: { type: Number, default: 9999 }, discount: { type: Number, default: 10 } },
    },
    currentStock: {
      type: Number,
      default: 0,
      min: [0, 'Stock cannot be negative'],
    },
    lowStockThreshold: {
      type: Number,
      default: 10,
      min: [0, 'Threshold cannot be negative'],
    },
  },
  { 
    timestamps: true,
    toJSON: { virtuals: true },
    toObject: { virtuals: true }
  }
);

productSchema.index({ 'variants.barcode': 1 });
productSchema.index({ 'variants.sku': 1 });

productSchema.virtual('stock').get(function() {
  return getTotalStock(this);
});

productSchema.virtual('stockStatus').get(function() {
  if (this.variants && this.variants.length > 0) {
    const total = getTotalStock(this);
    if (total === 0) return 'OUT_OF_STOCK';
    const avgThreshold =
      this.variants.reduce((s, v) => s + (Number(v.lowStockThreshold) || 0), 0) /
      this.variants.length;
    if (total <= avgThreshold) return 'LOW_STOCK';
    return 'IN_STOCK';
  }
  if (this.trackingType === 'SIZE' && this.sizeVariants && this.sizeVariants.length > 0) {
    const total = this.sizeVariants.reduce((sum, v) => sum + (v.stock || 0), 0);
    const avgThreshold = this.sizeVariants.reduce((sum, v) => sum + (v.lowStockThreshold || 5), 0) / this.sizeVariants.length;
    if (total === 0) return 'OUT_OF_STOCK';
    if (total <= avgThreshold) return 'LOW_STOCK';
    return 'IN_STOCK';
  }
  if (this.currentStock === 0) return 'OUT_OF_STOCK';
  if (this.currentStock <= this.lowStockThreshold) return 'LOW_STOCK';
  return 'IN_STOCK';
});

export default mongoose.model('Product', productSchema);
