import mongoose, { Document, Schema } from 'mongoose';

export interface IProductVariant {
  size: mongoose.Types.ObjectId;
  color: mongoose.Types.ObjectId;
  sku: string;
  price: number;
  comparePrice?: number;
  inventory: number;
  images: {
    url: string;
    altText?: string;
    sortOrder: number;
  }[];
}

export interface IProduct extends Document {
  name: string;
  slug: string;
  description: string;
  shortDescription?: string;
  category: mongoose.Types.ObjectId;
  subcategory?: mongoose.Types.ObjectId;
  sizes: mongoose.Types.ObjectId[];
  variants: IProductVariant[];
  isActive: boolean;
  isFeatured: boolean;
  seoTitle?: string;
  seoDescription?: string;
  createdAt: Date;
  updatedAt: Date;
}

const ProductSchema: Schema = new Schema({
  name: {
    type: String,
    required: [true, 'Product name is required'],
    trim: true,
    maxlength: [200, 'Product name cannot exceed 200 characters']
  },
  slug: {
    type: String,
    required: [true, 'Product slug is required'],
    unique: true,
    trim: true,
    lowercase: true
  },
  description: {
    type: String,
    required: [true, 'Product description is required'],
    maxlength: [5000, 'Description cannot exceed 5000 characters']
  },
  shortDescription: {
    type: String,
    maxlength: [500, 'Short description cannot exceed 500 characters']
  },
  category: {
    type: Schema.Types.ObjectId,
    ref: 'Category',
    required: [true, 'Category is required']
  },
  subcategory: {
    type: Schema.Types.ObjectId,
    ref: 'Category'
  },
  sizes: [{
    type: Schema.Types.ObjectId,
    ref: 'Size',
    required: [true, 'At least one size is required']
  }],
  variants: [{
    size: {
      type: Schema.Types.ObjectId,
      ref: 'Size',
      required: [true, 'Size is required for variant']
    },
    color: {
      type: Schema.Types.ObjectId,
      ref: 'Color',
      required: [true, 'Color is required for variant']
    },
    sku: {
      type: String,
      required: [true, 'SKU is required for variant'],
      unique: true,
      trim: true,
      uppercase: true
    },
    price: {
      type: Number,
      required: [true, 'Price is required for variant'],
      min: [0, 'Price cannot be negative']
    },
    comparePrice: {
      type: Number,
      min: [0, 'Compare price cannot be negative']
    },
    inventory: {
      type: Number,
      required: [true, 'Inventory is required for variant'],
      min: [0, 'Inventory cannot be negative'],
      default: 0
    },
    images: [{
      url: {
        type: String,
        required: [true, 'Image URL is required'],
        validate: {
          validator: function(v: string) {
            return /^https?:\/\/.+/.test(v) || v.startsWith('/');
          },
          message: 'Image URL must be a valid URL or relative path'
        }
      },
      altText: {
        type: String,
        maxlength: [200, 'Alt text cannot exceed 200 characters']
      },
      sortOrder: {
        type: Number,
        default: 0
      }
    }]
  }],
  isActive: {
    type: Boolean,
    default: true
  },
  isFeatured: {
    type: Boolean,
    default: false
  },
  seoTitle: {
    type: String,
    maxlength: [60, 'SEO title cannot exceed 60 characters']
  },
  seoDescription: {
    type: String,
    maxlength: [160, 'SEO description cannot exceed 160 characters']
  }
}, {
  timestamps: true,
  toJSON: { virtuals: true },
  toObject: { virtuals: true }
});

// Pre-save hook to generate slug
ProductSchema.pre<IProduct>('save', function(next) {
  if (this.isModified('name') && !this.slug) {
    this.slug = this.name
      .toLowerCase()
      .replace(/[^a-zA-Z0-9]/g, '-')
      .replace(/-+/g, '-')
      .replace(/^-|-$/g, '');
  }
  next();
});

// Indexes for better performance
ProductSchema.index({ category: 1, isActive: 1 });
ProductSchema.index({ subcategory: 1 });
ProductSchema.index({ isFeatured: 1, isActive: 1 });
ProductSchema.index({ name: 'text', description: 'text' });

export default mongoose.models.Product || mongoose.model<IProduct>('Product', ProductSchema);